定義了算法族(一組行爲),分別封裝起來(封裝實現),讓他們之間能夠相互替換(擴展),此模式讓算法的變化(擴展)獨立與使用算法的客戶(解耦);算法
舉例: 在一些外部網關,如銀行網關設計時,因直連模式時會接入多個銀行,這些銀行的具體報文封裝邏輯、解析邏輯、業務邏輯不一樣(實現ConcreteStrategy),但其均可抽象爲共用的網關處理邏輯(接口Strategy);爲減小調用方對實現的依賴關係、便於接入其餘銀行、共用代碼邏輯的複用,可採用策略模式進行設計;json
多個相似行爲的抽象,Context所依賴的接口bash
Strategy的具體實現,爲Context提供具體邏輯實現數據結構
上下文(客戶),一個具備多種行爲的類,持有strategy引用ide
Context 與Strategy關係爲一對多,Strategy與ConcreteStrategy關係爲一對多測試
工廠模式、模板方法優化
測試代碼ui
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);
}
}
複製代碼
簡單演示動態行爲切換this
/**
* @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簡單描述了策略模式是如何實現可複用、可擴展、可維護的OO思想;
另外此demo仍有很大的優化空間,須要你們發散思惟;spa
測試代碼
/**
* 測試
*/
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);
}
}
複製代碼