为什么要有设计模式?是只有软件领域才有设计模式么?这是很有意义的问题,但留待以后探讨。但现在,我们至少看到,设计模式对于如何组织代码,甚至是思考如何创造代码,有很大的帮助。
所以,今天我们就在最浅层的应用层面,认知几个设计模式的重点,以便改善我们的代码创造过程。
工厂模式
在知名的设计模式中,有很多种工厂模式,他们都有一个共同点:
把创造对象的过程封装起来
为什么要把对象的构造过程封装起来,可能的原因有:
- 你需要大量转换参数的代码,才能创造一个对象
- 你需要根据不同的参数,创造不同的对象
如果我们把这个需要大量代码的构造过程封装进一个方法,自己或别人在创建类似的对象时,就可以直接应用工厂方法,方便很多。
利用工厂模式,你最终会得到一个创造好的对象。之后需要这个对象做什么,就是你自己的事情了(这是工厂类的单一职责),后面可能还需要跟上其他的设计模式。
策略模式
如果你要得到一个结果,但有另外一些参数控制着这个结果的计算过程(也因此控制了结果),我们当然会想到根据控制位参数的不同,来判断具体执行哪个计算过程。
但,有些具体的执行过程有相似性,并且要求这些执行过程可以进行微调,怎么来组织代码?
可以这样:
- 把不同种类的执行过程(Strategy)封装为对象的方法,需要微调的部分由对象的属性来控制(也就是说,创造对象时附上不同的属性,你就能得到不同的具体执行过程 ConcreteStrategy)
- 根据控制位参数的不同,选择不同的对象
- 利用得到的对象(代表不同的执行过程)来计算你要的结果
因为细节上不同的执行过程,我们是可以通过构建不同的 Strategy 对象来控制,所以我们是不怕的。而一个全新种类的执行过程,我们可以新写一个 ConcreteStrategy 类来实现,不用更改以前的代码。所以,这个模式解决了需要很多种不同计算过程的需求,比如促销需求的公司(电商)应该会经常利用这种「策略模式」吧。
装饰模式
抽象的说,装饰者模式是把拥有统一调用方法(一种接口的概念)不断嵌套的模式。
一些框架中的中间件是这样的,比如 Rails。
Rails middlewares因为调用的接口统一,所以第一层调用第二层,和第二层调用第三层的方法是没有区别的,完全可以把第一层变为第二层:
1 -> 2 -> 3
2 -> 1 -> 3
为了实现这种装饰者模式,首先需要构建一个调用的链条(链表结构):
class Decorator1
def initialize(next:)
@next = next
end
end
class Decorator2
def initialize(next:)
@next = next
end
end
这样,decorator_link_list = Decorator1.new(next: Decorator2.new(next: XXX))
,就组成了一个链条。但是这个链条不可能无限的续接下去,也就是 XXX 的部分应该有个特殊的值,他不再需要拥有下一个装饰者。这个值就是我们真正在装饰的对象,比如叫 Component。
这个被装饰的 component 尽管不需要有下一个装饰者,但还是会被上一个装饰者调用,所以他应该有一些和装饰者一样的执行方法:
class Component
def do_something
puts "component did something"
end
end
class Decorator1
def do_something
puts "decorator1 didi something"
@next.do_something
end
end
class Decorator2
def do_something
puts "decorator2 didi something"
@next.do_something
end
end
这样,上面提到的 decorator_link_list
就是一个有始有终的完整链条,起点是最外层的装饰者,终点是最内层的被装饰者。而这个链条的执行,可以由起点启动(也就是最外层的装饰者): decorator_link_list.do_something
。
而且,装饰者内部调用下一个装饰者的位置不同(也就是上例中 @next.do_something
的不同),决定了这个链条是先进先出(先加入嵌套的先执行,队列,上面的例子就是),还是后进先出(后加入嵌套的先执行,栈)
这种模式适合实现那些有插入执行步骤、转换执行顺序、其他步骤保持不变的需求的产品。
比如什么产品呢?
网友评论