设计模式— 策略模式

上节我们谈到做一个鸭子的游戏,把共有的方法(游泳)作为父类,有变化的行为(飞,叫)作为接口,进而实现,满足各类鸭子去使用,那那我们该如何将它组合起来呢?

首先,在Duck 里面加入 FlyBehaviour 和 QuackBehaviour的实例变量,为接口类型,再添加可以执行的方法

performFly 和performQuack.

public class Duck {
	public FlyBehaviour flyBehaviour;
	public QuackBehaviour quackBehaviour;
	
	public void performFly(){
		flyBehaviour.fly();
	}
	public void performQuack(){
		quackBehaviour.quack();
	}
	public void swin(){
		// 游泳
	}
}

 下面我们看绿头鸭的类:

public class MallarDuck extends Duck{
	public MallarDuck(){
                // 这里用呱呱叫,可以飞
                // 当perform 被调用时候,行为就委托给接口,我只需要得到叫或者飞的结果就行了
		super.quackBehaviour = new QuackOne();
		super.flyBehaviour = new FlyWithWing();
	}
	
	public void display(){
		// 绿头鸭
	}
}

 这里我们发现,构造里面使用了new + 实现类,并且这里限定了绿头鸭叫的方式和飞的方式,也不灵活,

在原则中有一个是:针对接口编程(针对超类编程)

为了更加灵活,让我们的鸭子有更多的 叫的模式 和飞行模式。这样设计:

public class Duck {
	public FlyBehaviour flyBehaviour;
	public QuackBehaviour quackBehaviour;
	
	// 加入两个 设值方法,方便动态的改变行为方式
	public void setFlyBehaviour(FlyBehaviour flyBehaviour) {
		this.flyBehaviour = flyBehaviour;
	}
	public void setQuackBehaviour(QuackBehaviour quackBehaviour) {
		this.quackBehaviour = quackBehaviour;
	}
	public void performFly(){
		flyBehaviour.fly();
	}
	public void performQuack(){
		quackBehaviour.quack();
	}
	public void swin(){
		// 游泳
	}
}

 上面类暂时不变,后面其他模式 代替这种写法。

   现在假设 我们添加了一种新的飞行,NewFly.要求绿头鸭在特定情况下,可以使用新的模式

public class NewFly implements FlyBehaviour{

	@Override
	public void fly() {
		// 这是一种新的飞行模式
		System.out.println("fly 2");
	}
}

 让我们进行测试:

public class Test {
	public static void main(String[] args) {
		Duck f1 = new MallarDuck();
		f1.performFly();
		// 换飞行模式
		f1.setFlyBehaviour(new NewFly());
		f1.performFly();
	}

}

 现在已经可以随意的进行变化的,至于构造器那里,可以想想如何去完善。

小结 :我们这里分享思路:

1.将公共部分,放在超类里面使用

2.有变化的行为提炼成接口,提供实现类,提高代码的灵活性和复用性

3.所有的行为不用自己去实现,交给执行为的方法,我们只负责调用

4.为了让某种行为可以出现多种变化,或者多种方式,以属性注入接口,可以动态控制

策略模式:定义了算法(行为),分别封装起来,让你过他们之间可以相互转换,此模式让算法的变化独立于使用算法的客户。(摘自设计模式)

猜你喜欢

转载自greemranqq.iteye.com/blog/1828776