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

【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();
	}

	@Override
	public void display() {
		System.out.println("i am a model duck!");
	}
}
step3)建立一个新的 FlyBehavior 类型(FlyRocketPowered.java)
package com.designpattern.chapter0;

public class FlyRocketPowered  implements FlyBehavior{

	@Override
	public 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):
r 1)封装变化;
r2)多用组合,少用继承;
r3)针对接口编程,不针对实现编程;

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值