1. 什么是策略模式
策略模式(Strategy)属于对象行为型设计模式。主要是定义一系列的算法,把这些算
法一个个封装成拥有共同接口的单独的类,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化
例:甲乙两人在不同的地点,去同一个电影院看电影,他们有共同的属性(包括姓名、性别、到影院的时间等),此时到影院的时间计算方式(甲步行,乙驾车),即为策略模式所描述的算法。
2. 策略模式角色
策略使用环境角色(Context):策略被引用到这里和一些其它的与环境有关的操作一起来完成任务。
抽象策略角色(Strategy):规定了所有具体策略角色所需的接口。通常由接口或者抽象类来实现。
具体策略角色(Concrete Strategy):实现抽象策略角色定义的接口的具体策略。

三者关系图
3. 什么时候使用
- 系统需要能够在几种算法中快速的切换。
- 系统中有一些类它们仅行为不同时,可以考虑采用策略模式来进行重构
- 系统中存在多重条件选择语句时,可以考虑采用策略模式来重构。
4. 策略模式优缺点
优点:
- 策略模式符合开闭原则。
- 避免使用多重条件转移语句,如if...else...语句、switch 语句
- 使用策略模式可以提高算法的保密性和安全性。
缺点:
- 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
- 代码中会产生非常多策略类,增加维护难度。
5. 策略模式举例代码
策略使用环境角色(Context)
package design.model;
import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;
public class Animal {
/**
* 名字
*/
private String name;
/**
* 身高
*/
private Double height;
/**
* 体重
*/
private Double weight;
/**
* 颜色
*/
private String color;
/**
* 移动方式
*/
private MoveBehavior moveBehavior;
/**
* 叫声
*/
private CallBehavior callBehavior;
public Animal() {
}
public Animal(String name, Double height, Double weight, String color, MoveBehavior moveBehavior, CallBehavior callBehavior) {
this.name = name;
this.height = height;
this.weight = weight;
this.color = color;
this.moveBehavior = moveBehavior;
this.callBehavior = callBehavior;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public String getColorEnum() {
return color;
}
public void setColorEnum(String colorEnum) {
this.color = colorEnum;
}
@Override
public String toString() {
return "Animal{" +
"name=" + name +
", height=" + height +
", weight=" + weight +
", color=" + color +
", moveWay=" + moveBehavior.moveWay() +
", callWay=" + callBehavior.callWay() +
'}';
}
}
抽象策略角色(Strategy)
package design.behavior;
public interface CallBehavior {
String callWay();
}
package design.behavior;
public interface MoveBehavior {
String moveWay();
}
具体策略角色(Concrete Strategy):
package design.behavior.impl;
import design.behavior.CallBehavior;
public class JiJiCall implements CallBehavior {
@Override
public String callWay() {
// 业务逻辑
return "叫声为叽叽";
}
}
package design.behavior.impl;
import design.behavior.CallBehavior;
public class WoWoCall implements CallBehavior {
@Override
public String callWay() {
// 业务逻辑
return "叫声为喔喔";
}
}
package design.behavior.impl;
import design.behavior.MoveBehavior;
public class CreepWay implements MoveBehavior {
@Override
public String moveWay() {
// 业务逻辑
return "移动方式为爬行";
}
}
package design.behavior.impl;
import design.behavior.MoveBehavior;
public class FlyWay implements MoveBehavior {
@Override
public String moveWay() {
// 业务逻辑
return "移动方式为飞行";
}
}
package design.behavior.impl;
import design.behavior.MoveBehavior;
public class WalkWay implements MoveBehavior {
@Override
public String moveWay() {
// 业务逻辑
return "移动方式为行走";
}
}
测试代码
package design.model;
import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;
public class Bird extends Animal {
public Bird() { }
public Bird(String name, Double height, Double weight, String colorEnum, MoveBehavior moveBehavior, CallBehavior callBehavior) {
super(name, height, weight, colorEnum, moveBehavior, callBehavior);
}
}
package design.model;
import design.behavior.CallBehavior;
import design.behavior.MoveBehavior;
public class Monkey extends Animal{
public Monkey() { }
public Monkey(String name, Double height, Double weight, String color, MoveBehavior moveBehavior, CallBehavior callBehavior) {
super(name, height, weight, color, moveBehavior, callBehavior);
}
}
package design.test;
import design.behavior.impl.FlyWay;
import design.behavior.impl.JiJiCall;
import design.behavior.impl.WalkWay;
import design.behavior.impl.WoWoCall;
import design.model.Animal;
import design.model.Bird;
import design.model.Monkey;
public class AnimalTest {
public static void main(String[] args) {
Animal animal1 = new Monkey("金丝猴", 120d, 5d, "金色", new WalkWay(), new WoWoCall());
System.out.println(animal1);
System.out.println("----------------");
Animal animal2 = new Bird("燕子", 10d, 0.3d, "白色", new FlyWay(), new JiJiCall());
System.out.println(animal2);
}
}
// 控制台打印:
Animal{name=金丝猴, height=120.0, weight=5.0, color=金色, moveWay=移动方式为行走, callWay=叫声为喔喔}
----------------
Animal{name=燕子, height=10.0, weight=0.3, color=白色, moveWay=移动方式为飞行, callWay=叫声为叽叽}