设计模式入门(策略模式)

来源:互联网 发布:实用电子产品知乎 编辑:程序博客网 时间:2024/05/17 22:06
【0】README
0.1)本文部分文字描述转自 “head first 设计模式”,旨在学习 设计模式入门(策略模式) 的基础知识;
0.2)本文章节4和5的source code,参见 设计模式——策略模式源代码

【1】看个荔枝(从模拟鸭子应用说起)

1.1)我们让鸭子飞起来:
method1)利用继承实现:在Duck中加入 fly() 方法,不过并不是所有的鸭子都会飞,比如橡皮鸭子;(干货——继承所出现的问题)
Attention)利用继承来提供Duck的行为,这会导致下列哪些缺点(defects):
d1)代码在多个子类中重复;
d2)运行时的行为不容易改变;
d3)很难知道所有鸭子的全部行为;
d4)改变会牵一发而动全身,造成其他鸭子不想要的改变;
method2)利用接口实现:这将导致一个问题,虽然Flyable 和 Quackable 可以解决问题,但是代码不能复用;(干货——接口实现所出现的问题)

【2】设计原则
2.1)原则1:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;
2.2)原则2:针对接口编程,而不是针对实现编程;
2.3)针对接口编程的真正意思是:针对超类编程,可以更明确地说成“变量的声明类型应该是超类型,可以是一个抽象类或一个接口,只要是具体实现此超类的子类,都可以指定给这个变量”;(干货——针对接口编程)

【3】solution——如何实现鸭子的行为(我们应该在鸭子类中包含设定行为的方法,这样就可以在运行时动态地改变绿头鸭的行为。)
3.1)我们有两个接口——FlyBehavior 和 QuackBehavior;

3.2)对以上设计的分析(Analysis):
A1)这样一来,可以让飞行和呱呱叫(quack)的动作被其他对象复用,因为这些行为与鸭子类无关了;
A2)而我们新增一些行为,不会影响到既有的行为类,也不会影响 使用这些行为的 具体类,如鸭子类;

【4】整合鸭子的行为
4.1)关键在于: 鸭子现在会将飞行和呱呱叫的动作委托别人进行处理,而不是使用定义在Duck类内的 呱呱叫和飞行方法;
4.2)整合后的代码如下:



【5】动态设定行为
5.1)我们想通过在鸭子子类中通过“设定方法”来设定鸭子的行为,而不是在鸭子的构造器内实例化;
step1)在Duck类中,加入两个新方法: setFlyBehavior 和 setQuackBehavior;
package com.designpattern.chapter0;public abstract class Duck {FlyBehavior flyBehavior;QuackBehavior quackBehavior;public Duck(){}public void setFlyBehavior(FlyBehavior fb){flyBehavior = fb;}public void setQuackBehavior(QuackBehavior qb){quackBehavior = qb;}public abstract void display();public void performFly(){flyBehavior.fly();}public void performQuack(){quackBehavior.quack();}public void swim(){System.out.println("i am swiming!");}}
step2)制造一个新的鸭子类型:模型鸭(ModelDuck.java)
package com.designpattern.chapter0;public class ModelDuck extends Duck{public ModelDuck(){quackBehavior = new Quack();flyBehavior = new FlyWithWings();}@Overridepublic void display() {System.out.println("i am a model duck!");}}
step3)建立一个新的 FlyBehavior 类型(FlyRocketPowered.java)
package com.designpattern.chapter0;public class FlyRocketPowered  implements FlyBehavior{@Overridepublic void fly() {System.out.println("i am flying with rocket power!");}}
step4)改变测试类,加入模型鸭,并使模型鸭具有火箭动力;
package com.designpattern.chapter0;public class ModelDuckSimulator {public static void main(String[] args) {Duck mallard = new MallardDuck();mallard.performQuack();mallard.performFly();Duck modelDuck = new ModelDuck();modelDuck.performFly();modelDuck.setFlyBehavior(new FlyRocketPowered());modelDuck.performFly();}}
5.2)组合定义:将两个类结合起来使用,这就是组合。这种做法和继承不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象组合来的;
5.3)设计原则: 多用组合,少用继承;

【6】封装行为的大局观
6.1)下面是整个重新设计后的类结构,你所期望的一切都有: 鸭子继承Duck,飞行行为实现 FlyBehavior接口,呱呱叫行为实现 QuackBehavior接口;


6.2)我们不再把鸭子的行为说成是 一组行为,而是将其想象成“一族算法”;

6.3)策略模式定义: 策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户;(干货——策略模式定义)

【7】策略模式总结:
7.1)OO原则(rules):
r1)封装变化;
r2)多用组合,少用继承;
r3)针对接口编程,不针对实现编程;

7.2)OO模式(pattern):
策略模式——策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户;



0 0
原创粉丝点击