策略模式定义:定义一组通过方法的接口,然后各个实现类实现该接口,然后再定义一个类将各个实现类封装起来以屏蔽实现类的细节。
策略模式中,有三个模块:
- 策略接口模块,用来定义一个公共的策略方法;
- 策略实现类模块,公共策略方法的具体实现;
- 实现类封装模块,用于封装每个具体策略实现类,以屏蔽实现细节;
下面以做选择题为例:
定义选择策略接口:
public interface ChoiceQuestion {
void choiceStrategy();
}
分别定义两个选择策略:
public class ChoiceC implements ChoiceQuestion{
@Override
public void choiceStrategy() {
System.out.println("啥也不会,就选C");
}
}
public class ChoiceLong implements ChoiceQuestion {
@Override
public void choiceStrategy() {
System.out.println("三短一长,就选长");
}
}
定义学生类:
public class Student {
private ChoiceQuestion choiceQuestion;
public Student(ChoiceQuestion choiceQuestion) {
this.choiceQuestion = choiceQuestion;
}
public void choice() {
choiceQuestion.choiceStrategy();
}
}
定义业务类:
public class Test {
public static void main(String[] args) {
Student student1 = new Student(new ChoiceC());
Student student2 = new Student(new ChoiceLong());
student1.choice();
student2.choice();
}
}
啥也不会,就选C
三短一长,就选长
从结果可知,student1和student2有不同的选择策略。当我们需要新增策略的时候,只需要创建新的实现类实现策略接口即可,符合开闭原则。当然,我们可以看出每个策略都是一个实现类,策略过多也到知道类的数目过多。
策略模式与工厂模式
策略模式和工厂方法模式是非常相似的,上面例子中的ChoiceC和ChoiceLong可以理解为工厂方法模式中的工厂实现类,ChoiceQuestion接口可以理解为抽象工厂。而策略模式比工厂方法模式多出来的内容便是再创建一个封装类,接收工厂创建好的对象,调用共同的方法就可以执行不同的策略,好处就是屏蔽实现细节,降低类之间的耦合度。
虽然策略模式屏蔽了策略的实现细节,但是系统中有多少种策略并没有屏蔽,业务类需要提前知道系统中的策略种类。