策略模式工作中应该怎么玩
01策略模式简介
策略模式(Strategy Pattern):类似于"方案库"。提前准备好不同的解决方案,并使它们像插件一样,随时被选用和替换,动态实现业务需要。
策略模式有三个成员
- Strategy:声明的策略接口,供客户端调用。比如你要去远方旅游,需要选择一种交通方式,这个出行的交通方式可以理解为是抽象出来的方法。
- Concrete Strategy: 具体的策略算法实现,如坐火车、飞机、汽车等等交通方式。
- Context:上下文,持有策略的引用。
02基础代码实现
以用户交通出行为例:
交通工具抽象接口
java
/**
* 策略抽象接口 - 交通工具
*/
public interface TransportationStrategy {
/**
* 交通方式
*/
void transport();
}
具体交通工具实现
java
/**
* 2. 具体策略类 - 飞机
*/
public class AirplaneStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("✈️ 乘坐飞机");
}
}
/**
* 2. 具体策略类 - 火车
*/
public class TrainStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("🚄 乘坐火车");
}
}
/**
* 2. 具体策略类 - 汽车
*/
public class CarStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("🚗 驾驶汽车");
}
}
策略上下文:
java
/**
* 策略上下文
*/
public class TransportContext {
private TransportationStrategy strategy;
/**
* 通过构造函数,初始化strategy对象
*/
public TransportContext(TransportationStrategy strategy) {
this.strategy = strategy;
}
/**
* 执行具体的策略方法
*/
public void doTransport() {
strategy.transport();
}
/**
* 手动变更策略
*/
public void setStrategy(TransportationStrategy strategy) {
this.strategy = strategy;
}
}
新建一个main方法执行下:
java
public static void main(String[] args) {
TransportContext context = new TransportContext(new CarStrategy());
context.doTransport();
context.setStrategy(new AirplaneStrategy());
context.doTransport();
context.setStrategy(new TrainStrategy());
context.doTransport();
}
执行结果:
shell
🚗 驾驶汽车
✈️ 乘坐飞机
🚄 乘坐火车
03 项目实战
以上是简化版的策略代码,但在项目中我们一般将具体的对象交由spring容器来管理使用。借助工厂 + 策略来完成业务功能研发。
将业务对象进行改造,首先新建一个枚举类,用于标识不同的出行方式:
java
/**
* 交通方式枚举类
*/
@Getter
public enum TransportEnum {
/**
* 飞机
*/
AIRPLANE,
/**
* 汽车
*/
CAR,
/**
* 火车
*/
TRAIN,
}
其次,我们在抽象接口中新增交通方式类型方法,方便各个交通方式声明自己所属的类型:
java
/**
* 策略抽象接口 - 交通工具
*/
public interface TransportationStrategy {
/**
* 交通方式
*/
void transport();
/**
* 交通类型
*/
TransportEnum getType();
}
对应的具体实现类我们也需要调整下
- 声明自己的类型
- 交由spring容器管理
typescript
/**
* 2. 具体策略类 - 飞机
*/
@Component
public class AirplaneStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("✈️ 乘坐飞机");
}
@Override
public TransportEnum getType() {
return TransportEnum.AIRPLANE;
}
}
/**
* 2. 具体策略类 - 火车
*/
@Component
public class TrainStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("🚄 乘坐火车");
}
@Override
public TransportEnum getType() {
return TransportEnum.TRAIN;
}
}
/**
* 2. 具体策略类 - 汽车
*/
@Component
public class CarStrategy implements TransportationStrategy {
@Override
public void transport() {
System.out.println("🚗 驾驶汽车");
}
@Override
public TransportEnum getType() {
return TransportEnum.CAR;
}
}
具体的工厂实现:
java
/**
* 交通方式工厂
*/
@Component
public class TransportationFactory implements InitializingBean {
@Resource
private ApplicationContext applicationContext;
/**
* 交通方式策略映射
*/
private static final Map<TransportEnum, TransportationStrategy> TRANSPORT_MAP = new ConcurrentHashMap<>();
/**
* 获取交通方式策略
*
* @param transportEnum 交通方式枚举
* @return 交通方式策略
*/
public TransportationStrategy getTransportation(TransportEnum transportEnum) {
return TRANSPORT_MAP.get(transportEnum);
}
@Override
public void afterPropertiesSet() throws Exception {
applicationContext.getBeansOfType(TransportationStrategy.class)
.values()
.forEach(strategy -> {
TRANSPORT_MAP.put(strategy.getType(), strategy);
});
}
}
以上,我们的spring容器化改造就完成啦,接下来搞个简单的测试类,我们试一下吧 😊😊😊
less
@RestController
@RequestMapping("/strategy")
public class TestStrategyController {
@Resource
private TransportationFactory factory;
@GetMapping("/test")
public void test() {
factory.getTransportation(TransportEnum.AIRPLANE).transport();
factory.getTransportation(TransportEnum.TRAIN).transport();
factory.getTransportation(TransportEnum.CAR).transport();
}
}
控制台输出:
shell
✈️ 乘坐飞机
🚄 乘坐火车
🚗 驾驶汽车
好了,以上就是本期的内容,希望大家能喜欢,新人创作,感谢支持 !!!