场景:一个模拟鸭子的游戏,游戏中有各类鸭子,鸭子会叫,会游泳。
初步设计方案图如下uml类图所示:
Change:这个初期看上去无懈可击,直到有一天游戏需要鸭子会飞,此时最简单的解决方案莫过于在父类中增加一个fly方法,uml图如下所示:
有一天灾难发生了:游戏中有很多橡皮鸭飞来飞去。。。。
此时最简单的解决方案莫过于:覆盖掉RubberDuck类中的fly方法,类图如下:
Change:游戏越来越受欢迎,除了橡皮鸭,还有很多各种各样的鸭子加入了进来,如DecoyDuck(诱饵鸭),不会叫也不会飞,我们也要每一个类都去覆盖一遍fly、quack方法吗?
解决方案:
一、将fly和quack设计成接口,只有会叫会飞的鸭子来继承,相应的uml类图如下:(下图有误,decoyduck中不需要swim方法)
弊端:这种方案容易造成代码重复,没有复用相同的fly和quack方法
二、将flyable和quackable做成一个独立的类,当做鸭子的属性,相应的uml类图如下:
在此方法中,redheadduck、rubberduck、mallardduck和decoyduck得分别使用flyablity、quackablity类中的相关方法来实现特定fly和quack方法。这种方案违背了设计思想中的“针对接口编程,不针对具体实现编程”的原则,不能保证flyablity、quackablity类中一定存在各类鸭子需要的function
三、将flyable和quackable设计成接口,具体实现由各类飞行技能和叫声技能来完成。
Uml类图示意如下:
当然情况还是在变,橡皮鸭现在飞不起来不代表他以后也飞不起来,我们需要有一个方法来设定他的飞行能力,类图如下:
代码下载:下载代码(http://www.walk-sing.com/strategy策略模式.zip)
注:在实际代码编写过程中发现quack在实现quackable之后再使用quack方法时,quack方法手机上也是quack的构造方法,所以在编写时将quack类名改成了quacking类,望知悉。
以上就介绍了设计模式入门-策略模式(php版),包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。