设计模式 策略模式(Strategy Pattern)
策略模式简绍
策略模式(Strategy Pattern)是一种行为设计模式,它使你能在运行时改变对象的行为。该模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户而变化。
组成部分:
- 环境(Context)类:它含有一个Strategy类型的成员变量,并且有一个方法与Strategy类型关联,通常会提供一个设置Strategy对象的方法。
- 策略接口(Strategy):定义了一个统一的算法操作抽象接口。
- 具体策略类(Concrete Strategies):实现了策略接口中定义的算法。
策略模式优缺点
优点:
- 易于理解和实现:策略模式的概念简单明了,实现也不复杂。
- 提高系统维护性:策略模式将一系列的算法封装在一个个独立的类中,使得可以方便地增加新的算法或者改进已有算法而不影响客户端代码。
- 增强系统的灵活性:策略模式允许在运行时动态地更改算法或行为,增强了系统的灵活性。
- 符合开闭原则:新的算法可以自由添加到系统中而不影响现有的客户端代码,因为客户端是通过策略接口来访问算法的。
缺点:
- 客户端必须了解所有的策略类:客户端需要知道所有可用的策略类,并自行决定使用哪一个策略,这增加了客户端的复杂度。
- 策略类的增加导致类的数目增加:每增加一种算法都需要新增一个策略类,如果算法很多,则会导致系统中类的数量急剧增加。
- 过多的子类可能导致系统复杂化:如果策略类太多,可能会导致系统难以管理和理解。
- 在某些情况下,策略模式可能不如继承有效:如果所有可能的变化都来源于同一个维度,那么继承可能比组合更合适。
UML图
以下代码示例图,ConcreteStrategiesA,ConcreteStrategiesB 实现了 Strategy 接口
实现代码
策略接口(Strategy):
定义了一个名为 Strategy 的接口,包含一个 adapter 方法,用于适配不同的接口类型。
public interface Strategy {
void adapter(String port);
}
具体策略类(Concrete Strategies):
ConcreteStrategiesA 实现了 Strategy 接口,并提供了针对手机接口的适配逻辑。
ConcreteStrategiesB 实现了 Strategy 接口,并提供了针对电脑接口的适配逻辑。
public class ConcreteStrategiesA implements Strategy{
@Override
public void adapter(String port) {
System.out.println("手机接口" + port);
}
}
public class ConcreteStrategiesB implements Strategy{
@Override
public void adapter(String port) {
System.out.println("电脑接口" + port);
}
}
环境类(Context):
Context 类持有策略对象,并提供了一个 adapter 方法,用于调用策略对象的 adapter 方法。
通过构造函数注入策略对象,使得 Context 可以在运行时动态地选择不同的策略。
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public void adapter(String prot){
strategy.adapter(prot);
}
}
主类(Main):
创建了两个不同的 Context 对象,分别使用 ConcreteStrategiesA 和 ConcreteStrategiesB。
调用 adapter 方法,输出不同的适配信息。
public class Main {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategiesA());
context.adapter("usb-c");
Context context1 = new Context(new ConcreteStrategiesB());
context1.adapter("usb-c");
}
}
常用场景
- 算法选择
当存在多种算法可以实现同一功能时,可以使用策略模式来动态地选择和切换算法。例如,在排序算法中,可以选择冒泡排序、快速排序、插入排序等多种算法。 - 行为配置
在某些场景下,需要根据不同的配置或上下文来选择不同的行为。例如,在游戏中,角色可能具有不同的攻击策略,如近战攻击、远程攻击或魔法攻击。 - 多种配置选项
在某些应用中,需要根据不同的配置来选择不同的处理方式。例如,在数据处理中,可能需要选择不同的数据格式进行读取或写入。
策略模式非常适合以下场景:
- 需要在运行时动态选择算法或行为。
- 存在多种实现方式,但实现方式的细节不应该影响到客户端。
- 需要将算法的实现与使用算法的客户端相分离。
通过策略模式,可以将算法的实现与使用算法的客户端相分离,使得系统更加灵活和可扩展