策略模式

设计模式之策略模式

以前听说过设计模式,但没有了解、学习过,最近买了本《Head First设计模式》来看,感觉设计模式真是太妙了!!!想来实在惭愧,现在才开始学习设计模式!

我技术好菜啊

1.定义

策略模式(Strategy Pattern)是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

2.实例说明

比如现在就想实现很简单的功能——学生在学习,老师在授课。学习和授课都是角色当前的一个动作、状态,我们可以把这一类随时可变的动作从角色里抽离出来并封装起来。

2.1 动作接口

首先定义一个动作接口,所有的具体动作都要实现这个接口。

1
2
3
public interface Action {
public void action();
}

2.2 具体动作实现接口

接下来就是具体动作了,授课、学习、睡觉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 授课动作
public class TeachAction implements Action {
@Override
public void action() {
System.out.println("正在授课!");
}
}

// 学习动作
public class LearnAction implements Action{
@Override
public void action() {
System.out.println("正在学习!");
}
}

// 睡觉动作
public class SleepAction implements Action {
@Override
public void action() {
System.out.println("正在睡大觉!");
}
}

2.3 Person抽象类

定义抽象类 Person,在该类里加入两个实例变量,一个是字符串变量name,一个是Action接口类型action(而不是具体类实现类型)。方法doing()里调用action的action()方法。Person抽象类不用关心action的具体对象到底是什么,它只需关心该对象能有action()就行了。并且建一个setAction()来通过动态改变action的具体实现类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class Person {
Action action;
String name;

public Person(){
}

public void doing() {
System.out.print(name);
action.action();
}

public void setAction(Action action){
this.action = action;
}
}

2.4 具体角色类继承Person类

Teacher类在构造时将action实例变量初始化为TeachAction的新实例,而Student类则将action实例变量初始化为LearnAction的新实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Teacher类
public class Teacher extends Person{
public Teacher(String name) {
this.action = new TeachAction();
this.name = name + "老师";
}
}

// Student类
public class Student extends Person {
public Student(String name){
this.action = new LearnAction();
this.name = name + "同学";
}
}

3.测试

测试代码和测试结果如下。

1
2
3
4
5
6
7
8
9
10
public static void main(String args[]){
Person handsomeDong = new Teacher("帅比东");
Person xiaoQiang = new Student("小强");

handsomeDong.doing();
xiaoQiang.doing();

xiaoQiang.setAction(new SleepAction());
xiaoQiang.doing();
}

测试结果

4.优缺点

4.1 优点

1.算法可以自由切换,改策略很方便
2.增加一个策略,就多增加一个类实现接口就好了。

4.2 缺点

每一个策略都是一个类,复用的可能性很小、类数量增多

5.适用场景

1.许多相关类仅仅是行为不同。
2.需要使用一个算法的不同实现。
3.算法使用了客户不应该知道的数据。策略模式可以避免暴露复杂的、与算法相关的数据结构。