策略模式

本篇博客来源于 Head First (原创总结)

策略模式 :定义了算法类,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

 Joe在公司上班,要设计一款鸭子游戏,游戏中会出现各种类型的鸭子拥有不同的行为,(游泳,呱呱叫、飞...) ,Joe很容易的就想到了 设计一个superClass ,  让各种鸭子集成这个超类就好了。


1、现在有新的需求,为了击败竞争对手,项目经理让Joe设计一只会飞的鸭子。 Joe一想这有什么难的,一分钟搞定。于是在超类里面 加了一个 fly()方法; 第二天可怕的事情发生了,游戏中满屏的木头鸭子飞来飞去。原来在父类中加入fly()会导致所有的子类鸭子都具有会飞的能力。 


2、Joe又想到了 重写父类中 fly() 方法, 木头鸭重写 

fly(){
//什么都不做     
}

但是以后如果有橡皮鸭 同样也不会飞,也不会叫,要覆盖所有的方法吗?,所以使用继承 会牵一发而栋全身,造成其他鸭子不想要的改变,另外也很难知道所有鸭子的行为,运行时的
行为不容易改变等问题。
3、Joe又想到了接口 把超类中的 fly()取出来放在 FlyInterface里面,只有会飞的鸭子才去实现这个接口,也可以设计一个QuackInterface接口,因为不是所有的鸭子都会叫。
但大牛说这是一个超级笨的方法,你没发现 这么一来重复的代码会变得更多吗? 如果你认为覆盖几个方法就算差劲,那么 让你稍微改变一下48个Duck的子类的飞行行为,你又怎么说
如果你是Joe,你怎么办???

把问题归零

接口看似解决了问题,但是接口不具有实现代码的能力,所有继承接口无法达到代码的复用,这意味着:无论何时你需要修改某个行为,你必须得往下追踪并在每一个定义此行为的类中去修改它。幸运的是有一个设计模式,恰好适用此状况。
  把会变得部分取出来,并封装起来。而不去影响不需要变化的部分,好的,是时候把鸭子的行为 从Duck类中取出来了。
4、现在有两个接口,FlyInterface 和 QuackInterface 负责实现具体的行为
public interface FlyInterface {
	abstract void fly();
}

public interface QuackInterface {
	abstract void quack();
}
这样设计,这些行为已经与鸭子类无关了

首先在Duck中加入 两个实力变量   FlyInterface  、 QuackInterface 
每只鸭子对象 都会动态的设置这些变量以在运行时引用正确的行为 
public abstract class Duck {
	
	FlyInterface flyInterface;
	QuackInterface quackInterface;
	
	abstract void disPlay();
	
	public void swiming(){
		System.out.println("是鸭子都会游泳");
	}
	
	public void performFly(){
		if(flyInterface !=null)
		flyInterface.fly();
	}
	
	public void performQuack(){
		if(quackInterface!=null)
		quackInterface.quack();
	}
	
	
	public void setFlyBehave(FlyInterface flyInterface){
		this.flyInterface = flyInterface;
	}
	
	public void setQuackBehace(QuackInterface quackInterface){
		this.quackInterface = quackInterface;
	}
	
}

下面我们暂定义 4种行为 分别去 继承 FlyInterface  、 QuackInterface  接口 会飞、不会飞、会叫、不会叫四种行为
public class FlyDuck implements FlyInterface{

	public void fly() {
		System.out.println("我会飞");
	}

}

public class NotFlyDuck implements FlyInterface{

	public void fly() {
		System.out.println("我不会飞");
	}

}

public class Quack implements QuackInterface{

	public void quack() {
		System.out.println("我会叫");
	}

}

public class NotQuack implements QuackInterface{

	public void quack() {
		System.out.println("我不会叫");
	}

}


下面我想 实现一个会飞会叫的野鸭子 
public class MallardDuck extends Duck {
	
	public MallardDuck(){
		this.flyInterface = new FlyDuck();
		this.quackInterface = new Quack();
	}
	
	void disPlay() {
		System.out.println("我是绿头鸭");
	}

}

Test类

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MallardDuck mallardDuck = new MallardDuck();
		mallardDuck.performFly();
		mallardDuck.performQuack();
		
		System.out.println();
		mallardDuck.setFlyBehave(new NotFlyDuck()); 动态的去赋予鸭子行为
		mallardDuck.setQuackBehace(new NotQuack());
		mallardDuck.performFly();
		mallardDuck.performQuack();
	}

}




总结 :一种行为相当于一种算法,我们在实力类中根据具体情况去组装 相应的算法(行为),及灵活又可以达到代码的复用 。









 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值