【设计模式与体系结构】行为型模式-策略模式
简介
策略模式(Strategy Pattern)定义一系列的类,每个类封装一个算法,并且使它们之间可以相互转换,这些封装了算法的类可以称为策略。为保证这些策略在使用时具有一致性,一般会提供一个抽象策略类来制定规则,而每种策略对应一个具体策略类。
策略模式的角色
- 抽象策略(Strategy)类:它为所声明的算法声明抽象接口,所有具体策略类都需要实现该接口
- 具体策略(Concrete Strategy)类:实现抽象策略类定义的接口,每个具体策略类都包含具体的算法实现
- 环境(Context)类:持有抽象策略类的引用,客户端通过调用环境类的方法来执行具体策略。环境类可以根据不同的用户或条件,动态切换具体策略对象
策略模式的优点
- 符合开闭原则
- 可维护性强:面向抽象编程,将算法封装在具体策略类中,满足单一职责原则和依赖倒转原则,代码结构清晰,易于维护和理解
- 灵活性高:环境类可以根据不同情景,动态更换策略模式
- 代码复用性好
策略模式的缺点
- 增加系统复杂性:具体策略类数量多,可能会导致系统较为复杂
- 客户端需要了解策略类:客户端需要知道有哪些具体策略可供选择,并且需要了解它们之间的差异,以便选择合适的策略,这可能会增加客户端的使用难度
- 策略类之间存在耦合:如果不同策略类之间存在复杂的依赖关系或共享关系,可能会导致耦合性大,以致于开发和维护的难度极大
策略类的使用场景
- 算法多样化且可互相转化:在许多业务场景中,会有多种不同的算法来解决同一个问题,例如不同的排序算法、加密算法等。策略模式可以让这些算法独立存在,并且可以在运行时根据需要轻松地切换算法
- 行为随条件而变化:当对象的行为需要根据不同的条件或环境进行变化时,策略模式可以将这些不同的行为封装成不同的策略类,使得代码更加清晰和易于维护。比如,电商系统中根据不同的促销活动计算商品价格
- 代码复用和扩展:如果有一些算法或行为在多个地方被重复使用,将它们封装成策略类可以提高代码的复用性。同时,当需要添加新的算法或行为时,只需要创建新的策略类,而不会影响到其他已有的代码,符合开闭原则
正文
每年春运,都会有大量的返乡人员(说个笑话,25年了很多人还买不到一张票)。这些返乡人员通常会有多种多样的交通工具的进行选择,这些交通工具的交通时间、价格等各有差异,不同的人群往往会有不同的选择。一款出行软件对不同交通方式的选择,可以采取策略模式进行处理。下面就以交通工具的选择作为案例,进行代码分析。
声明一个抽象交通策略类 VehiclesStrategy.java
public interface VehiclesStrategy {
void travel();
}
声明小轿车交通策略类 CarStrategy.java
public class CarStrategy implements VehiclesStrategy {
@Override
public void travel() {
System.out.println("乘坐小轿车出行");
}
}
声明飞机交通策略类 PlaneStrategy.java
public class PlaneStrategy implements VehiclesStrategy {
@Override
public void travel() {
System.out.println("乘坐飞机出行");
}
}
声明一个交通环境类 VehicleContext.java
public class VehicleContext {
private VehiclesStrategy strategy;
public VehicleContext(VehiclesStrategy strategy) {
this.strategy = strategy;
}
public void travel() {
strategy.travel();
}
public void setStrategy(VehiclesStrategy strategy) {
this.strategy = strategy;
}
}
写一个客户端
public class Client {
public static void main(String[] args) {
VehiclesStrategy planeStrategy = new PlaneStrategy();
VehicleContext vehicleContext = new VehicleContext(planeStrategy);
vehicleContext.travel();
VehiclesStrategy carStrategy = new CarStrategy();
vehicleContext.setStrategy(carStrategy);
vehicleContext.travel();
}
}
运行效果截图如下:

浙公网安备 33010602011771号