设计模式-策略模式
来源:互联网 发布:js toggle 编辑:程序博客网 时间:2024/05/29 04:43
今天看完了head first设计模式,现在每一种模式按照自己的理解整理一遍~ 首先是策略模式
1.设计背景
假如你刚为老板完成了一套相当成功的模拟鸭子游戏,游戏中会出现各种鸭子。你采用面向对象的思想来设计这些鸭子,使用一个超类,并让所有鸭子继承这个类。超类中有三个方法,两个具体方法分别是quack呱呱叫和swim游泳,还有一个抽象方法display,因为每个鸭子外观不同,所以定义抽象方法让子类去实现。类图如下所示:
2.新的需求---尝试更改
上面的设计虽好,但是这时候老板有了新的需求,它要给每个鸭子添加一个fly方法,让鸭子有飞的行为。嘿嘿!既然所有鸭子都要有fly方法, 我们直接把fly放在超类里面就好啦,也就是在超类定义具体方法。看起来没什么问题,但是上面提到过,我们的鸭子实在多,其中也包括橡皮鸭子,而橡皮鸭子不会飞,因此继承fly方法会导致橡皮鸭子飞起来,难以接受!
于是你想到让不会飞的鸭子全都重写超类的fly方法,但是这个实在太麻烦啦!以后每次增加一种鸭子,都必须考虑鸭子会不会飞,然后要考虑重写父类方法。而且目前只有一个fly方法,但是其实并不是所有鸭子都会呱呱叫,现在就是fly和quark两个方法的问题,未来还可能更多。那么利用接口怎么样呢?把fly和quark的行为抽象出来,分别做成两个接口,会飞的鸭子实现flyable接口,会呱呱叫的实现quarkable接口。类图如下:
这个设计虽然麻烦了一点,但是基本上可以满足我们的需求啦。但是你有没有发现,这样一来我们的fly和quark方法代码完全没法复用了。因为每个实现接口的鸭子类只能自己实现自己的fly和quark方法。这样也很麻烦,我们需要可以复用的代码,也需要更加简化的类图。
3.解决方法-策略模式
记住一个设计原则:把应用中可能经常变化的部分独立出来,不要和那些稳定不变的代码混在一起。这样可以方便我们扩展功能。
在这个问题中,我们知道fly和quark方法会随着鸭子的不同而改变,因此我们可以把fly和quark的行为从Duck超类中分离出来,用一组新的类来代表每个行为。我们用接口代表每个行为,而行为的每个实现都将实现其中一个接口。如下图:
我们这样的设计可以让飞行和呱呱叫的动作被其他对象复用,因为这些已经和鸭子无关了。我们甚至可以很轻松的增加新的行为,只需要另外定义接口就可以啦!
接下来我们在Duck超类中加入两个实例变量,如下图:
然后把飞行和呱呱叫的行为委托给对象的实例对象(也就是Duck的属性),我们必须在构造方法中实例化这两个属性,还必须实现每个属性的setter和getter方法。这样的设计才是正宗的策略模式。从此以后鸭子的呱呱叫行为就像下面一样委托给了quackBehavior属性对象了。而我们可以使用setter方法随时替换这个属性对象。使用策略模式,以后不管增加再多的行为(只需要设计相应的行为接口和实现类,然后给Duck加上一个属性对象和相应的方法,稍微修改构造方法),或者增加再多的鸭子我们都可以迅速完成,几乎不需要更改原有代码,这样的设计十分具有弹性,我们再也不怕该需求啦!
4.策略模式的正式定义
5.这个模式涉及的设计原则总结
- 设计模式-策略模式
- 设计模式:策略模式
- 设计模式-策略模式
- 设计模式 - 策略模式
- 设计模式-策略模式
- 设计模式-----策略模式
- 设计模式 策略模式
- 设计模式-策略模式
- 设计模式-【策略模式】
- 设计模式-----策略模式
- 设计模式-策略模式
- 设计模式--策略模式
- 设计模式- 策略模式
- 设计模式- 策略模式
- 设计模式------策略模式
- 设计模式--策略模式
- 设计模式-策略模式
- 设计模式--策略模式
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 E Maximum Flow
- Jquery学习笔记
- vagrant中centos编译安装php7.1.9
- 【XSY1295】calc $n$个点$n$条边无向连通图计数 prufer序列
- LCA(最近公共祖先)Tarjan算法
- 设计模式-策略模式
- 个人对sendmessage理解
- 零基础学编程流程-成为自由人
- RYU REST API学习-调用示例
- C语言结构体全通详解
- ORA-12560:TNS: 协议适配器错误 问题解决
- okhttp网络请求简介
- Linux 命令大全
- HTTP状态码简介