策略模式
定义
策略模式定义了一个算法族,让他们之间可以相互替换,这样就会使得算法的改变独立于使用算法的客人
Strategy is a behavioral design pattern that lets your define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
应用实例
1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。
Java Code
项目介绍
我们要实现模拟鸭子的代码,我们认为这个世界上,鸭子都可以呱呱叫(quack),都可以游泳(swim),现在使用继承完成的鸭子的代码:
遇到的难题
现在我们为鸭子加入新的功能飞翔(fly),但是并不是所有鸭子都能飞翔,比如橡皮鸭子(RubberDuck), 那么我们就不能在超类中增加这个功能了,否则就会导致橡皮鸭子也能飞。
不恰当的解决办法
这就是一个非常糟糕的主意,这样会让重复的代码变得很多。因为随着鸭子的增多,我们要实现Flyable接口会变多。
解决思路
因为Java的接口没有实现的功能,所有继承接口不能达到代码的复用。这意味着无论我们何时想要修改某个行为都需要追踪到具体类中修改它,但是这样就会在类中造成新的bug.
现在引出第一个设计原则
设计原则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
在这个例子中,鸭子的飞翔行为就是会变得地方,现在把它们抽取出来。
现在我们在看之前的设计方法
这样的设计还有一个问题就是:行为来自DUCK超类的具体实现,或者继承自某个接口并且由子类继承而来。这两种方法都依赖于实现。我们不能更改行为。
我们在新的设计中,鸭子的子类将使用接口(FlyBehavior)所表示的行为,我们实际的实现不会被绑在具体的鸭子子类中。(也就是说,特定的具体行为编写在实现了FlyBehavior中)
上边的改进使用了实际原则
针对接口编程而不是针对具体实现编程
最终结果
这样的设计:可以让飞行的动作被其它对象复用,因为这些行为已经和鸭子类无关了。
我们可以增加一些新的飞行行为,但这样不会影响到使用飞行行为的鸭子。
在最终结果中,我们使用了组合的方法,也就是说,鸭子都有一个FlyBehavior,这样将飞行委托给他们的行为代理。将两个类组合在一起,这就是组合(composition)
设计原则
多用组合,少用继承
具体代码:
python: https://github.com/beishangongzi/DesignPatternByPython.git
java: https://github.com/beishangongzi/DesignPatternByJava.git