您的位置:首页 > 其它

head first设计模式(一)——策略模式

2016-01-26 11:56 260 查看
最近在看《head first设计模式》这本书,很有趣。这系列文章算是我对书中一些内容的总结吧!

问题:写一个鸭子类描述各种鸭子的行为和特征,包含许多种鸭子,红头鸭,绿头鸭,橡皮鸭等等。有的鸭子会飞,有的鸭子会叫。当然,橡皮鸭是不会飞的。我们不但要正确的实现每一个类,还要代码的结构最优,即如果更改了一个方法,不会在每一个子类中去修改这个方法。

方案一:继承

有一些特征是各个鸭子子类所共有的,因此可以想到继承。

新的问题:可是有的子类有其独特的方法。如果在duck父类中实现了quack和fly方法,那么橡皮鸭也就有了这两个方法,这显然是不行的。如果在duck父类中把quack和fly定义为抽象方法,那么对于红头鸭和绿头鸭需要重复实现这两个方法,复用性差(主要体现在一旦fly方法需要修改那么将要去红头鸭,绿头鸭等实现了fly方法的类中修改代码)。

方案二:接口

把fly,quack方法定义成接口,这样可以避免橡皮鸭也能够fly的荒谬现象。

新的问题:接口中不负责方法的实现,fly和quack还是需要在红头鸭和绿头鸭等子类中实现,复用性差。

方案三:由于不同子类中的fly,quack方法具体实现不同,因此把fly,quack等行为从duck类中抽取出来,即不在duck类和子类中实现fly,quack方法

将fly方法封装成flybehavior接口,由具体实现fly方法的类来实现这个接口(例如flywithwings,flynoway)。这里需要强调下针对接口编程

针对接口编程

目的:可以针对父类进行操作而不需要深入各个子类。举个例子:

Dog d = new Dog();
d.bark;


描述了狗叫的行为,这是针对子类狗的实现。而

Animal animal = new Dog();
animal.makeSound();


也实现了相同的行为,可我们是对父类Animal操作的。这样就避免了代码的重复操作。

我们把fly和quack接口作为成员变量放入duck父类中,由它们负责实现duck类的fly和quack方法,例如

public class Duck{
FlyBehavior flyBehavior;
//...
public void fly(){
flyBehavior.fly();
}
}
这样,在不同的子类中我们子在构造器中为他传输不同的fly实现类即可使它们的fly方法各不相同。例如红头鸭的FlyBehavior类为FlyWithWings,橡皮鸭的FlyBehavior类为FlyNoWay。

这里我们用到了组合的方式来实现fly和quack这两个方法而不是继承(之前在《java编程思想》中也看到过“多用组合,少用继承”)。即我们把一族行为封装成接口放到duck类的成员变量中。

策略模式:把一族可以替换的算法封装起来(接口),对于每一个算法我们用一个类来实现。然后把这个接口作为成员变量嵌入到使用这族算法的其他类中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: