标签:
面向对象的设计方案
产品狗今天跟你说,要做一个“模拟鸭子游戏”,需求如下:
鸭子有共同的功能,比如游泳和叫。
鸭子也有不同的功能,比如有绿头鸭和红头鸭。
所以想到了通过使用OO的方式,将共同的功能放在抽象类Duck中,而不同的用abstract修饰供子类实现。
public abstract class Duck { public Duck() { } public void Quack() { System.out.println("~~gaga~~"); } public abstract void display();//不同样子的鸭子,有不同的实现 public void swim() { System.out.println("~~im swim~~"); } } public class GreenHeadDuck extends Duck {//绿头鸭 @Override public void display() { System.out.println("**GreenHead**"); } } public class RedHeadDuck extends Duck {//红头鸭 @Override public void display() { System.out.println("**RedHead**"); } }
通过面向对象的思想,我们实现了复用,完成了需求。
新需求
看看这种设计在增加新功能的时候,其扩展性如何。
新需求:添加会飞的鸭子
public abstract class Duck { //...略... public void Fly() { System.out.println("~~im fly~~"); } }
如果在超类中添加这段代码,那么问题马上就来了,超类中添加的方法对所有之类都生效,而不是所有的鸭子都需要这个功能。
public class GreenHeadDuck extends Duck { //...略... public void Fly() { System.out.println("~~no fly~~"); } }
那我们可以覆盖掉不会飞的鸭子的fly方法,不就可以了吗~~~
问题又来了,如果有10种不会飞的鸭子,岂不是要重复做10次重复性的工作?
那可不可以把超类中的fly方法弄成abstract呢?
这样所有的之类不就都要实现fly方法吗~如果50种鸭子,那就需要实现50次!
如果又有新需求,比如石头鸭子,既不会飞也不会叫 ,如何实现? +_+
看来上述都不是很好的设计方案。
思路
分析软件设计需要考虑两方面的问题
1)分析项目变化和不变的部分,对于变化的部分,抽象成接口+实现;
2)找到那些功能会根据新需求而变化。
这个模拟鸭子的游戏中,鸭子的叫声和飞行方式会变。
策略模式实现
对飞行和叫分别设计接口,对于不同的叫声和飞行再通过实现的方式完成。
public interface FlyBehavior { void fly(); } public interface QuackBehavior { void quack(); }
这样新增行为变得很简单,只需要实现相同的接口即可。
在鸭子超类中,通过组合抽象的飞行和抽象的叫声,具体的叫和飞交给之类补充。
import com.java.hexter.stimulateduck.flybehavior.FlyBehavior; import com.java.hexter.stimulateduck.quackbehavior.QuackBehavior; public abstract class Duck { FlyBehavior mFlyBehavior; QuackBehavior mQuackBehavior; public Duck() { } public void Fly() { mFlyBehavior.fly(); } public void Quack() { mQuackBehavior.quack(); } public abstract void display(); public void SetQuackBehavoir(QuackBehavior qb) { mQuackBehavior = qb; } public void SetFlyBehavoir(FlyBehavior fb) { mFlyBehavior = fb; } public void swim() { System.out.println("~~im swim~~"); } }
看到没有,抽象超类中没有任何具体的实现类耦合,而是通过接口调用。
里面的fly还是quack函数,都是根据之类mFlyBehavior和mQuackBehavior的不同而不同。
看看绿头鸭以及红头鸭的实现过程。
public class GreenHeadDuck extends Duck { public GreenHeadDuck() { mFlyBehavior = new GoodFlyBehavior(); mQuackBehavior = new GaGaQuackBehavior(); } @Override public void display() { System.out.println("**GreenHead**"); } } public class RedHeadDuck extends Duck { public RedHeadDuck() { mFlyBehavior = new BadFlyBehavior(); mQuackBehavior = new GeGeQuackBehavior(); } @Override public void display() { System.out.println("**RedHead**"); } }
很强大,又木有~~~ 脑洞打开的赶脚
策略模式:
行为抽象成接口,并且实现算法族,在超类中放行为接口对象,子类里具体设置行为对象。
原则是分离变化部分,封装接口,基于接口编程各种功能,让行为的实现能单独变化。
标签:
原文地址:http://my.oschina.net/gaohongtian/blog/492113