策略模式
来源:互联网 发布:微点主动防御软件 编辑:程序博客网 时间:2024/06/10 01:40
思维过程
业务场景
一个系统里面有鸭子类(抽象父类),有各种各样的鸭子(子类),这些鸭子都有叫quack、游泳swim、显示display方法。不同的鸭子显示不同的外观。如RedHeadDuck红头鸭,MallarDuck绿头鸭。初始基本关系如下:
问题一
现在有一些鸭子能飞,有一些不能飞;有一些鸭子能叫,有一些鸭子不能叫;怎么去定义方法呢?
不佳解决方法一
- 实现:在父类中写一个抽象的公共的fly方法,子类中进行重写。能飞的鸭子实现飞的行为,不能飞的鸭子实现空的行为。叫quack方法同理。
- 问题:每添加一个鸭子子类都要重写fly和quack方法,这简直就是噩梦。而且
- 思考:继承可能不是解决办法,可以想想接口。
不佳解决方法二
- 实现 : 针对飞和叫这两种行为,可以定义两个接口,有这样行为的鸭子便实现这两个接口即可。这样没有这些行为的鸭子就没有这些行为。类图如下:
- 解决:会飞的鸭子才能飞,会叫的鸭子才能叫。
- 问题:接口不具有实现代码,如果有50个鸭子子类,都会飞,那么就要实现50次,代码无法复用!!!
设计原则之独立原则
找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。这样系统中的某部分改变就不会影响其他部分。
由于行为变成动态的了,所以需要提供动态设定行为的方法,那么我们遵循下面的原则
设计原则之针对接口编程
针对接口编程,而不是针对实现编程
策略模式解决方法三
这样来设计这些动态改变的行为:
这样的设计,可以让飞行和呱呱叫的动作被其它对象复用,因为这些行为已经和鸭子类无关了。我们可以新增一些行为,不会影响到既有的行为类,也不会影响“使用”飞行行为的鸭子类。
在鸭子Duck的父类中,持有这些行为(算法)的引用,利用多态,就可以动态地改变这些行为了。最终类图如下:
Duck类中的属性说明:
- flyBehaviour:有一个飞行行为FlyBehaviour,组合,飞行行为委托给它去处理
- quackBehaviour:有一个叫的行为QuackBehaviour,组合,叫的行为委托给它去处理
Duck类中的方法说明:
- swim:鸭子游泳,同样的行为(算法),不会改变
- display:鸭子展现,抽象方法,每种鸭子有自己独特的展现方式,有自己实现
- performQuack:由quackBehaviour去执行quack方法
- performFly:由flayBehaviour去执行fly方法
- setQuackBehaviour:设置叫的行为(算法)
- setFlyBehaviour:设置飞的行为(算法)
设计原则之组合原则
多用组合,少用继承
通过组合建立系统具有很大的弹性。
策略模式
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
代码展现
飞行行为的代码
飞行接口
/** * 飞行行为的接口 */public interface FlyBehaviour { /** * 飞行行为 */ public void fly();}
用翅膀飞
/** * 用翅膀飞 */public class FlyWithWings implements FlyBehaviour { @Override public void fly() { System.out.println("用翅膀飞~"); }}
不会飞
/** * 不能飞 */public class FlyNoWay implements FlyBehaviour { @Override public void fly() { System.out.println("不能飞.."); }}
叫的行为的代码
叫的行为的接口
/** * 鸭子叫的行为接口 */public interface QuackBehaviour { /** * 叫的行为方法 */ public void quack();}
呱呱叫
/** * 呱呱叫 */public class Quack implements QuackBehaviour { @Override public void quack() { System.out.println("呱呱叫~"); }}
吱吱叫
/** * 吱吱叫 */public class Squack implements QuackBehaviour { @Override public void quack() { System.out.println("吱吱叫~"); }}
不会叫
/** * 不会叫 */public class MuteQuack implements QuackBehaviour { @Override public void quack() { System.out.println("不会叫.."); }}
关于鸭子类的代码
鸭子父类
/** * 鸭子的父类 */public abstract class Duck { /** 飞行行为 */ protected FlyBehaviour flyBehaviour; /** 叫的行为 */ protected QuackBehaviour quackBehaviour; /** * 鸭子展现 */ public abstract void display(); /** * 鸭子游泳 */ public void swim() { System.out.println("鸭子在游泳~~"); } /** * 鸭子飞行 */ public void performFly() { flyBehaviour.fly(); } /** * 鸭子叫 */ public void performQuack() { quackBehaviour.quack(); } public FlyBehaviour getFlyBehaviour() { return flyBehaviour; } public void setFlyBehaviour(FlyBehaviour flyBehaviour) { this.flyBehaviour = flyBehaviour; } public QuackBehaviour getQuackBehaviour() { return quackBehaviour; } public void setQuackBehaviour(QuackBehaviour quackBehaviour) { this.quackBehaviour = quackBehaviour; }}
绿头鸭
/** * 绿头鸭,默认会飞会呱呱叫 */public class MallarDuck extends Duck{ /** * 在构造方法中,初始化飞行和叫的行为(后期会有更好的处理) */ public MallarDuck() { flyBehaviour = new FlyWithWings(); quackBehaviour = new Quack(); } @Override public void display() { System.out.println("绿头鸭"); }}
红头鸭
/** * 红头鸭,默认会飞会呱呱叫 */public class RedHeadDuck extends Duck{ public RedHeadDuck() { flyBehaviour = new FlyWithWings(); quackBehaviour = new Quack(); } @Override public void display() { System.out.println("红头鸭"); }}
橡皮鸭
/** * 橡皮鸭,默认不会飞,会呱呱叫 */public class RubberDuck extends Duck{ public RubberDuck() { flyBehaviour = new FlyNoWay(); quackBehaviour = new Quack(); } @Override public void display() { System.out.println("橡皮鸭"); }}
诱饵鸭
/** * 诱饵鸭,默认不会飞,不会叫 */public class DecoyDuck extends Duck { public DecoyDuck() { flyBehaviour = new FlyNoWay(); quackBehaviour = new MuteQuack(); } @Override public void display() { System.out.println("诱饵鸭"); }}
测试代码
public class TestClient { public static void showDuck(Duck duck) { duck.display(); duck.performFly(); duck.performQuack(); } public static void main(String[] args) { Duck duck = new RedHeadDuck(); showDuck(duck); System.out.println("------让此duck不会飞,和吱吱叫-----"); duck.setFlyBehaviour(new FlyNoWay()); duck.setQuackBehaviour(new Squack()); showDuck(duck); }}
输出结果如下:
红头鸭
用翅膀飞~
呱呱叫~
——让此duck不会飞,和吱吱叫—–
红头鸭
不能飞..
吱吱叫~
0 0
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- Windows下使用pip install各种奇奇怪怪的错误
- 《视频直播技术详解》之二:编码和封装、推流和传输
- 解题报告(4)——麻烦的聚餐
- 《视频直播技术详解》之三:延迟优化
- ARM寄存器介绍
- 策略模式
- internet协议入门
- React-Navite–ES6学习笔记(1)–了解与环境安装
- java堆和内存的区别,哪个更快?
- 现代视频播放器原理
- 【分治之二分答案】 衣服
- HDU 5934
- QML Chart之PieSeries系列(饼图)
- ImportError: pycurl: libcurl link-time ssl backend (openssl)