策略者模式
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(); } }
以上是关于策略者模式的主要内容,如果未能解决你的问题,请参考以下文章