设计模式之策略模式

xiaoxiao2021-02-28  48

策略模式

     最近买了一本关于java设计模式的新书《Head First 设计模式》,里面介绍了java 的23种设计模式。目前看了第一章介绍的策略模式,里面的内容很容易理解,但是让我自己用嘴说出来却又总感觉表达不是很清楚。正所谓温故知新,所以我打算把自己的理解以及书上的代码记录到这里,算是一个回顾的过程。

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

    这本书上介绍策略模式使用的是一个鸭子的对象,其中鸭子有很多属性:飞行、鸣叫、展现形式等。由于要做一个通用的鸭子对象模型,所以我们需要把把这个鸭子创建成一个抽象的对象,将所有鸭子的通用属性放在抽象类中,而将差异化的属性在继承类中实现。考虑到代码的可扩展性和后期的维护,又将继承的这种模式进行改变,将两个类结合起来使用,即组合的方式。这种做法和继承不同的地方在于,鸭子的行为不是继承来的,而是和适当行为对象“组合”来的。使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可。

设计原则:多用组合,少用继承。

先来一张整体设计图:

这张图展示了利用策略模式对鸭子对象的属性进行拆分和组合,将鸭子的飞行和鸣叫的行为委托给接口来处理,而固定属性则封装在抽象类中。

上代码:

Duck类

package com.my.duck; public abstract class Duck { //为行为接口类型声明两个引用变量,所有鸭子子类都继承它们。 FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck(){ } public abstract void display(); public void performFly(){ flyBehavior.fly();//委托给行为类 } public void performQuack(){ quackBehavior.quack();//委托给行为类 } public void swim(){ System.out.println("All ducks float,even decoys!"); } public void setFlyBehavior(FlyBehavior fb){//提供动态改变飞行行为的方法 flyBehavior = fb; } public void setQuackBehavior(QuackBehavior qb){//提供动态改变鸣叫行为的方法 quackBehavior = qb; } } FlyBehavior类

package com.my.duck; public interface FlyBehavior { public void fly();//所有飞行行为类必须实现的接口 } FlyBehavior的实现

package com.my.duck; public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("I'm flying !"); } } package com.my.duck; public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("I can't fly"); } } QuackBehavior接口

package com.my.duck; public interface QuackBehavior { public void quack(); } QuackBehavior实现

package com.my.duck; public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("Quack"); } } package com.my.duck; public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("<<Silence>>"); } } package com.my.duck; public class Squeak implements QuackBehavior { @Override public void quack() { System.out.println("Squeak"); } }

新建一个模型鸭子(ModelDuck)

package com.my.duck; public class ModelDuck extends Duck { public ModelDuck(){ flyBehavior = new FlyNoWay();//一开始模型鸭子不会飞行 quackBehavior = new Quack(); } @Override public void display() { System.out.println("I'm a model Duck"); } } 运行函数:

package com.my.duck; public class MiniDuckSimulator { public static void main(String[] args){ /*Duck mallard = new MallardDuck(); mallard.performFly(); mallard.performQuack();*/ Duck model = new ModelDuck(); //第一次调用performFly()会被委托给flyBehavior对象(也就是FlyNoWay实例),该对象是在模型鸭构造器中设置的。 model.performFly(); //这会调用继承来的setter方法,把火箭动力飞行的行为设定到模型鸭子中。 model.setFlyBehavior(new FlyRocketPowered()); //鸭子的飞行方式将变成乘坐火箭飞行器飞行。 model.performFly(); } } 运行效果:

转载请注明原文地址: https://www.6miu.com/read-54366.html

最新回复(0)