Strategy

来源:互联网 发布:vscode wordpress 编辑:程序博客网 时间:2024/06/01 15:28

这是我从《Head First 设计模式》这本书中学习到的第一个设计模式-策略模式。这本书的内容还是挺有趣的值得推荐。话不多说,进入正题。

首先谈一下策略模式的价值所在,书中是以设计鸭子的例子来讲解的。我这里主要说下我的理解。

在一些类中,某些行为是比较活跃的。比如一个Person类,这个类有一个say方法,表示人说话的行为,但是实际生活中,有些人说话比较快,有些人说话比较慢,有些人不会说话,那么怎样来设计Person类中say这个方法呢?你可能会想,新建一些子类,子类覆盖Person类的say方法来达到说话不一致的目的。如果又出现一种人说话不快不慢是不是又要新建一个子类呢?嗯这你可能觉得还不怎么麻烦,你还能接受。但是如果需求改变,需要为Person类新增加一个eat方法,但是有些人吃荤有些人吃素。这种情况下你还会用继承去实现子类么?

为了应对需求的改变,我们在设计类的时候一定要考虑扩展性、可维护性等。在书中我学到了第一个设计原则:“找出应用中可能需要变化之处,把他们独立出来不要和那些不变化代码混在一起”。再来看看我们设计的Person类。我们可以将say方法单独提取出来,进行单独设计。下面我记录下我设计Personl类的主要设计思路。

1:新建person类将可能变化的say方法交给接口SayBehaviour的实现类去实现。在Person类中生成SayBehaviour的setter方法,用于动态设置say的实现方式。


public class Person {  private String name;private int age;private SayBehaviour sayBehaviour;public void say(){sayBehaviour.say();}public SayBehaviour getSayBehaviour() {return sayBehaviour;}public void setSayBehaviour(SayBehaviour sayBehaviour) {this.sayBehaviour = sayBehaviour;}}
2 新建一个SayBehaviour接口并定义say方法

public interface SayBehaviour {void say();}

3 (可选) 新建一个SayBehaviourUtils 工具类,帮助say方法做一些辅助处理

public class SayBehaviourUtils {protected void preSay(){System.out.println("SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。");};}

4 新建三个表示不同说话方式的类

public class NoSay extends SayBehaviourUtils implements SayBehaviour{@Overridepublic void say() {preSay();System.out.println("no say");}}public class QuickSay extends SayBehaviourUtils implements SayBehaviour{@Overridepublic void say() {preSay();System.out.println("say quickly");}}public class SlowSay extends SayBehaviourUtils implements SayBehaviour{@Overridepublic void say() {preSay();System.out.println("say slowly");}}

5 新建一个测试类测试动态设置人的说话方式


public class StrategyTest {public static void main(String[] args){Person person1 = new Person();//定义一个人person1.setSayBehaviour(new QuickSay());//动态设置这个人说话的方式person1.say();Person person2 = new Person();//定义一个人person2.setSayBehaviour(new SlowSay());//动态设置这个人说话的方式person2.say();Person person3 = new Person();//定义一个人person3.setSayBehaviour(new NoSay());//动态设置这个人说话的方式person3.say();//神奇的是 如果person2遇到一个神医,治疗后person2会说话了而且说话还很快那么你可以在下面插入一条语句person3.setSayBehaviour(new QuickSay());person3.say();}}

输出结果:

SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
say quickly
SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
say slowly
SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
no say

SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
say quickly
SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
say slowly
SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
no say
SayBehaviourUtils:我是say方法的工具类,我可以帮助说话这个方法做一些辅助工作。
say quickly

这个例子为say方法单独设计了一个接口,通过不同的实现类实现这个接口去表示say方法的不同行为,在通过person的setSayBehaviour这个方法动态设置say方法的表现形式,来表达这个人说话的方式。你可以在此基础上设计Person类eat方法的不同变现形式。














原创粉丝点击