策略模式

前言

关于设计模式,我想写一个简单的笔记,方便知识的记忆。该笔记主要参考了《Head First 设计模式》这本书。

策略的提出

先写一个“水果”类:

1
2
3
public class Fruit {
}

大部分人都爱吃水果,但这部分人对不同的水果又有不同的喜好。水果的一些特质可以分为两部分:

  • 一部分指的是广泛被接受的,比如干净,估摸着很少有人喜欢吃不干净的水果;
  • 一部分指的是颜色、酸甜等等,不同的人对此接受程度是不一样的,可以用UniqueHobby接口抽象出来。

策略的实施

我们首先来写可能不会变化的部分,这里我就单列干净程度:

1
2
3
4
5
public abstract class Fruit {
...
public abstract void cleanliness ();
}

接下来要处理喜好可能有差别的部分,首先把这一部分抽象出来:

1
2
3
public interface UniqueHobby {
public void uniqueHobby();
}

接下来实现不同特质:

1
2
3
4
5
6
7
8
9
10
11
public class Kind1 implements UniqueHobby {
public void uniqueHobby() {
System.out.println("红色水果!");
}
}
public class Kind2 implements UniqueHobby {
public void uniqueHobby() {
System.out.println("黄色水果");
}
}

接下来的问题是,抽象出来的特质如何在Fruit类中体现呢??其实,只需要声明成字段就可以了,同时为了执行抽象的行为,还要添加具体的实现方法,代码如下:

1
2
3
4
5
6
7
public abstract class Fruit {
UniqueHobby uniqueH;
public abstract void cleanliness();
public void performMethod() {
uniqueH.uniqueHobby();
}
}

接下来只要单独去实现各自的类,就能针对不同具体的水果指定方案了,以Orange方案为例:

1
2
3
4
5
6
7
8
public class Orange extends Fruit {
public Orange (UniqueHobby uh) {
uniqueH = uh;
}
public void cleanliness() {
System.out.println("水果已被服务人员清洗干净");
}
}

Ok,接下来我们写一个例子测试一下:

1
2
3
4
5
6
public class Test {
public static void main(String[] args) {
Fruit o1 = new Orange(new Kind1());
o1.performMethod();
}
}

设计模式的原则

从这个例子中,我们学到了三个设计模式原则:

  • 设计原则1:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。在该例子中,我把所有可变的需求首先用UniqueHobby接口抽象出来了,把他们单独弄在一边;
  • 设计原则2:针对接口编程,而不是针对实现编程,不需要new硬编码,而是在运行时才指定具体的实现对象。在本例子中,最大的体现在于WhitePlan类中的构造方法的写法。
  • 设计原则3:多用组合,少用继承。在本例子中,这一点体现在抽象类Human中声明成员变量那一步,即:UniqueHobby uniqueH;