策略者模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略者模式相关的知识,希望对你有一定的参考价值。

1.什么是策略模式?

定义算法族,将他们封装其起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户

2.什么情况下使用策略模式?

实现某一个功能有多条途径,每一条途径对应一种算法

将算法的定义与使用分开,也就是将算法的行为和环境分开

3.设计原则

a.找出应用中可能的变化之处,将他们独立出来,和不需要变化的代码分开

b.多用组合,少用继承

c.针对接口编程,不针对实现编程

4.代码情景

模拟鸭子游戏设计:游戏中会出现各种各样的鸭子,他们会游泳,会叫

设计思路:所有鸭子都具有游泳和叫的功能,因此可以设计一个超类,实现这两个方法,然后让不同的鸭子继承该超类,也可以设计一个显示方法,

由于不同的鸭子外观不一样,因此我们可以在超类中设计抽象的显示方法,让不同的子类去实现。


新需求:使鸭子可以飞起来

设计思路:在超类中加上fly()方法,让所有子类去继承,鸭子就可以飞起来了

出现的问题:按上面描述的方式编码之后,鸭子是可以飞起来了,但是橡皮类型的鸭子也开始起飞了,这不合乎逻辑

解决问题:可以让橡皮鸭继承的时候将fly()方法覆盖掉

思考:不同类型的鸭子叫声,飞行方式都不同,假如又出现新类型的鸭子,有需要覆盖哪些方法,显然使用继承的方式大大降低了代码的扩展性,

那么如果将飞和叫全部改为接口,不同类型的鸭子根据需求去实现这几个接口,貌似这样可以解决扩展性问题,但很快我们便会发现,代码的复用性很差,

产生大量的垃圾代码。

显然使用以上的方式是不可取的,需要重构代码。

新方案:将超类中的叫和飞方法从超类中分离出来,设为两个接口并且让特定的类去实现他们,不同类型的鸭子继承超类后调用相应的类的

飞和叫的方法。具体看代码

//飞行为的接口
public interface FlyBehavior {

	public void fly();
}
//叫行为的接口
public interface QuackBehavior {

	public void quack();
}
//鸭子的超类
public abstract class Duck {

	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
	
	public Duck() {
	}
	
	//将飞的行为委任给接口,具体调用什么样的实现由具体实现决定,此处为多态
	public void performFly() {
		flyBehavior.fly();
	}
	
	//将叫的行为委任给接口,具体调用什么样的实现由具体实现决定,此处为多态
	public void performQuack() {
		quackBehavior.quack();
	}
}
//会飞的鸭子的具体实现类
public class CanFly implements FlyBehavior {

	@Override
	public void fly() {

		System.out.println("我可以飞");
	}

}
//呱呱叫的鸭子的具体实现类
public class GagaDuack implements QuackBehavior {

	@Override
	public void quack() {

		System.out.println("呱呱呱");
	}

}
//不会飞类型鸭子的具体实现类
public class Nofly implements FlyBehavior {

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

}
//不会叫的鸭子
public class SilenceQuack implements QuackBehavior {

	@Override
	public void quack() {

		System.out.println(".........");
	}

}
//吱吱叫的鸭子的具体实现类
public class ZhizhiQuack implements QuackBehavior {

	@Override
	public void quack() {

		System.out.println("吱吱吱");
	}

}
//模型鸭子
public class ModelDuck extends Duck {

	public ModelDuck() {
		flyBehavior = new Nofly();
		quackBehavior = new SilenceQuack();
	}
	
}
public class TestApp {

	public static void main(String[] args) {
		Duck d = new ModelDuck();
		d.performFly();
		d.performQuack();
	}
}


以上是关于策略者模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式回顾:策略模式代理模式装饰者模式的区别

20.设计模式_策略者模式

设计模式-策略者模式

策略者模式小示例

20策略者模式(Strategy Pattern)

工厂模式策略者模式责任链模式综合应用