内容简介:定义了举例: 在一些外部网关,如银行网关设计时,因直连模式时会接入多个银行,这些银行的具体报文封装逻辑、解析逻辑、业务逻辑不同(多个类似行为的抽象,Context所依赖的接口
定义了 算法族 (一组行为),分别 封装 起来(封装实现),让他们之间可以 相互替换 (扩展),此模式让算法的 变化(扩展)独 立与使用算法的客户(解耦);
场景
- Strategy描述一组概念相同却行为不同(一个接口却实现不同)的相关类;
- Strategy的使用客户不应该知道其具体实现(解耦),避免暴露复杂的、与具体策略相关的数据结构;
- 一个类定义多种行为,避免这些行为以if-else的形式出现在此类中,减少对实现细节的依赖;
举例: 在一些外部网关,如银行网关设计时,因直连模式时会接入多个银行,这些银行的具体报文封装逻辑、解析逻辑、业务逻辑不同( 实现ConcreteStrategy ),但其都可抽象为共用的网关处理逻辑( 接口Strategy ); 为减少调用方对实现的依赖关系、便于接入其他银行、共用代码逻辑的复用 ,可采用策略模式进行设计;
结构
- Strategy
多个类似行为的抽象,Context所依赖的接口
- ConcreteStrategy
Strategy的具体实现,为Context提供具体逻辑实现
- Context
上下文(客户),一个具有多种行为的类,持有strategy引用
- 流程描述
Context 与Strategy关系为一对多,Strategy与ConcreteStrategy关系为一对多
推荐搭配
工厂模式、模板方法
代码实现
- 简单策略DEMO
测试代码
public class TransTest extends NnnToolsApplicationTests { @Autowired private Trans trans; @Test public void testTrans(){ TransDO transDO = new TransDO(); Invocation invocation = new Invocation(); invocation.setBizType("N00001"); invocation.setParam(transDO); //调用,外部对内部无感知,无依赖 //Trans内部只依赖行为接口,不依赖实现,可动态改变其行为实现 trans.transfer(invocation); } } 复制代码
简单演示动态行为切换
/** * @author hanlujun */ @Service public class TransImpl implements Trans { @Autowired private Map<String,Validator> validators; /** * 交易操作 * @param var1 * @return */ @Override public Result transfer(Invocation var1) { //**变化的行为** //获取对应业务类型的校验(如权限校验、非空校验、账户校验等) Validator validator = validators.get(var1.getBizType()); if(Objects.nonNull(validator)){ //校验 validator.validation(var1.getParam()); } //执行对应业务类型的业务逻辑 return accountOperation(var1).doTransfer(var1); } /** * 测试 */ public TransOperation accountOperation(Invocation var1){ // **变化的行为** return SpringContextUtil.getBean(var1.getBizType(), TransOperation.class); } } 复制代码
- 进阶策略DEMO
借鉴之前老师的写法来演示并做了稍微改动,demo简单描述了策略模式是如何实现可复用、可扩展、可维护的OO思想;
另外此demo仍有很大的优化空间,需要大家发散思维;
测试代码
/** * 测试 */ public class TransTest extends NnnToolsApplicationTests { @Autowired private StrategyFactory strategyFactory; public void testTrans(){ Context context = strategyFactory.makeDecision("N00001"); context.execute("N00001","{}"); } } 复制代码
策略接口
/** * 多个类似行为的抽象,Context所依赖的接口 */ public interface IStrategy { Response execute(String code, String jsonBody); } 复制代码
策略接口与具体实现结合并结合模板方法
/** * 多个类似行为的抽象,Context所依赖的接口,具体策略有子类实现 */ @Slf4j public abstract class AbstractStrategy implements IStrategy{ @Autowired private Map<String, Validator> validators; @Override public Response execute(String code , String jsonBody) { //获取对应业务类型的校验(如权限校验、非空校验、账户校验等) Validator validator = validators.get(code); if(Objects.nonNull(validator)){ //校验 validator.validation(jsonBody); } //执行对应业务类型的业务逻辑 return doTransfer(code); } /** * 具体实现由子类决定 * @param code * @return */ protected abstract Response doTransfer(String code); } 复制代码
策略模式中的客户Context
/** * 上下文(客户),一个具有多种行为的类,持有strategy引用 */ public class Context { private IStrategy strategy; private Context(IStrategy strategy){ this.strategy = strategy; } public static Context getInstance(IStrategy strategy){ return new Context(strategy); } /** * 执行策略 * @param code * @param jsonBody * @return */ public Response execute(String code, String jsonBody) { return strategy.execute(code,jsonBody); } } /** * 策略工厂 */ public interface IStrategyFactory { Context makeDecision(String code); } 复制代码
推荐搭配:工厂类
/** * 策略工厂 */ @Component public class StrategyFactory implements IStrategyFactory { @Override public Context makeDecision(String code) { String serviceName =BizTypeEnums.getServiceByCode(code); IStrategy strategy = SpringContextUtil.getBean(serviceName); return Context.getInstance(strategy); } } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。