1、概述
在软件开发中,我们也常常会遇到类似的情况,实现某一个功能有多条途径,每一条途径对应一种算法,此时我们可以使用一种设计模式来实现灵活地选择解决途径,也能够方便地增加新的解决途径。
譬如商场购物场景中,有些商品按原价卖,商场可能为了促销而推出优惠活动,有些商品打九折,有些打八折,有些则是返现10元等。
而优惠活动并不影响结算之外的其他过程,只是在结算的时候需要根据优惠方案结算
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
2、定义
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
3、角色
Context(环境类)
环境类是使用算法的角色,它在解决某个问题(即实现某个方法)时可以采用多种策略。在环境类中维持一个对抽象策略类的引用实例,用于定义所采用的策略。
Strategy(抽象策略类)
它为所支持的算法声明了抽象方法,是所有策略类的父类,它可以是抽象类或具体类,也可以是接口。环境类通过抽象策略类中声明的方法在运行时调用具体策略类中实现的算法。
ConcreteStrategy(具体策略类)
它实现了在抽象策略类中声明的算法,在运行时,具体策略类将覆盖在环境类中定义的抽象策略类对象,使用一种具体的算法实现某个业务处理。
4、实现
抽象策略类
public interface Strategy {
public void process();
}
具体策略类
public class StrategyImpl1 implements Strategy {
@Override
public void process() {
System.out.println("StrategyImpl1");
}
}
public class StrategyImpl2 implements Strategy {
@Override
public void process() {
System.out.println("StrategyImpl2");
}
}
环境类
public class StrategyContext {
Strategy strategy;
public StrategyContext(Strategy strategy) {
this.strategy = strategy;
}
public void deal() {
strategy.process();
}
}
测试
class Client{
public static void main(String[] args) {
StrategyContext context1 = new StrategyContext(new StrategyImpl1());
context1.deal();
System.out.println("==================");
StrategyContext context2 = new StrategyContext(new StrategyImpl2());
context2.deal();
}
}
结果:
StrategyImpl1
==================
StrategyImpl2
5、策略模式与spring集成实战
5.1 需求
与流程引擎组件对接,完成流程审批之后需要进行事件的回调,处理相关的业务逻辑。但是流程引擎传入的参数只有当前流程实例主键,表中有实例对应的模板类型,即属于哪个流程模板对应的实例。每个流程都有不同的模板,需要进行不同的设置。
5.2 实现
不同的流程模板枚举
package com.zengqingfa.examples.mybatisplus.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ProcessTypeEnum {
CREATE_WAREHOUSE(1, "aa创建审批"), UPDATE_WAREHOUSE(2, "bb变更申请"),
DELETE_WAREHOUSE(3, "cc仓库申请"), OVERSOLD_ADJUST(4,"dd调整");
private final Integer key;
private final String desc;
ProcessTypeEnum(int key, String desc) {
this.key = key;
this.desc = desc;
}
public static ProcessTypeEnum getEnum(Integer key) {
ProcessTypeEnum[] processTypeEnums = values();
for (ProcessTypeEnum processTypeEnum : processTypeEnums) {
if (processTypeEnum.getKey().equals(key)) {
return processTypeEnum;
}
}
return null;
}
}
策略接口
package com.zengqingfa.examples.mybatisplus.strategy;
import com.zengqingfa.examples.mybatisplus.enums.ProcessTypeEnum;
public interface ProcessStrategy {
/**
* 获取流程枚举
* @return
*/
ProcessTypeEnum getProcessTypeEnum();
/**
* 流程实例id
* @param processId
*/
String callBack(Long processId);
}
策略接口实现
实现1:
package com.zengqingfa.examples.mybatisplus.strategy.impl;
import com.zengqingfa.examples.mybatisplus.enums.ProcessTypeEnum;
import com.zengqingfa.examples.mybatisplus.strategy.ProcessStrategy;
import org.springframework.stereotype.Component;
@Component
public class CreateWarehouseStrategy implements ProcessStrategy {
@Override
public ProcessTypeEnum getProcessTypeEnum() {
return ProcessTypeEnum.CREATE_WAREHOUSE;
}
@Override
public String callBack(Long processId) {
System.out.println("CreateWarehouseStrategy....")