<>前言
筆者是金融保險行業,有這么一種場景,業務員錄完單后提交核保,這時候系統會對保單數據進行校驗,如不允許手續費超限校驗,客戶真實性校驗、費率限額校驗等等,當校驗一多時,維護起來特別麻煩,代碼耦合度太高。
這里使用責任鏈模式,將每個校驗模塊之間互相獨立,在后面新增校驗時,只需要往容器中插入即可,且可以給每個模塊賦予優選級進行排序,利于管理。與Spring框架結合,利于類的管理。
<>正文
<>處理器模板
public interface CheckProcessor { /** * 邏輯處理 * @param policyInfo * @param
exposeProcessor */ public void invoke(PolicyInfo policyInfo,ExposeProcessor
exposeProcessor) throws Exception; }
<>處理器實現類
<>手續費校驗器
public class CommissionRateCheckProcessor implements CheckProcessor { @Override
public void invoke(PolicyInfo policyInfo, ExposeProcessor exposeProcessor)
throws Exception { System.out.println("完成手續費校驗"); //調用下個處理器 exposeProcessor.
invoke(policyInfo); } }
<>客戶真實性校驗器
public class CustomerCheckProcessor implements CheckProcessor { @Override
public void invoke(PolicyInfo policyInfo, ExposeProcessor exposeProcessor)
throws Exception { System.out.println("完成客戶真實性校驗"); //調用下個處理器 exposeProcessor.
invoke(policyInfo); } }
<>保險費率校驗器
public class PremiumRateCheckProcessor implements CheckProcessor { @Override
public void invoke(PolicyInfo policyInfo, ExposeProcessor exposeProcessor)
throws Exception { System.out.println("完成保險費率校驗"); //調用下個處理器 exposeProcessor.
invoke(policyInfo); } }
<>入口管理類
public class ExposeProcessor { private int index; private static List<
CheckProcessor> processor=new ArrayList(); static { setProcessor(new
CustomerCheckProcessor()); setProcessor(new CommissionRateCheckProcessor());
setProcessor(new PremiumRateCheckProcessor()); } /** * 處理器 */ public void invoke
(PolicyInfo policyInfo) throws Exception { //獲取容器中所有的處理器 List processors =
getProcessors(); if (processors.size()==0||index==processors.size()){ return; }
//根據指針指向,調用處理器。并把指針指向下一個 CheckProcessor processor = (CheckProcessor)processors.
get(index++); //調用處理器 processor.invoke(policyInfo,this); } /** * 處理器集 */ private
List getProcessors(){ return processor; } public static void setProcessor(
CheckProcessor checkProcessor){ processor.add(checkProcessor); } }
* 獲取容器中的校驗器
* 校驗是否往下執行,如果處理器數量為空,或者當前指針已經指向尾部時,則不再往下執行
* 將管理器以及請求參數傳遞到處理器中進行處理
* 處理器執行完畢后,調用管理器的invoke方法來啟動責任鏈中的下個處理器
<>測試用例
public static void main(String[] args) { ExposeProcessor exposeProcessor=new
ExposeProcessor(); try { exposeProcessor.invoke(new PolicyInfo()); } catch (
Exception e) { e.printStackTrace(); } }
以前代碼有很多可以改進的地方,如與IOC框架結合,將每個處理器交給IOC容器進行管理,在獲取處理器方法中可以直接從IOC容器中獲取CheckProcessor
類型的所有實現類。
<>結合Spring IOC
@Service public class ExposeProcessor implements ApplicationContextAware {
private ApplicationContext applicationContext; private int index; private List<
CheckProcessor> processor=new ArrayList(); /** * 處理器 */ public void invoke(
PolicyInfo policyInfo) throws Exception { List processors = getProcessors(); if
(processors.size()==0||index==processors.size()){ return; } CheckProcessor
processor= (CheckProcessor)processors.get(index++); processor.invoke(policyInfo,
this); } /** * 處理器集 */ private List getProcessors(){ Map<String, CheckProcessor>
beansOfType= this.applicationContext.getBeansOfType(CheckProcessor.class);
return beansOfType.values().stream().collect(Collectors.toList()); } public void
setProcessor(CheckProcessor checkProcessor){ processor.add(checkProcessor); }
@Override public void setApplicationContext(ApplicationContext
applicationContext) throws BeansException { this.applicationContext=
applicationContext; } }
* 管理類實現ApplicationContextAware接口,并重寫其setApplicationContext方法,將IOC上下文對象保存下來。
* 從IOC容器中獲取類型為CheckProcessor 的類
* 將管理類加上@Service注解交由IOC容器進行管理
* 在所有的校驗器實現類上都加上@Service注解,交由IOC容器管理
測試:
public static void main(String[] args) { //創建Spring IOC容器,開啟注解掃碼
AnnotationConfigApplicationContext annotationConfigApplicationContext=new
AnnotationConfigApplicationContext("com.mashibing.dp.intepreter"); //獲取管理類
ExposeProcessor exposeProcessor= (ExposeProcessor)
annotationConfigApplicationContext.getBean("exposeProcessor"); try {
exposeProcessor.invoke(new PolicyInfo()); } catch (Exception e) { e.
printStackTrace(); } }
由于項目非Spring web項目,所以必須啟動Spring IOC容器,指定包路徑對注解進行掃碼,這樣才能將類交由容器進行管理,不然獲取會為空。
<>總結
責任鏈模式有多種寫法,具體需要根據業務場景進行定制化開發。
責任鏈模式的優點:
* 降低耦合度。它將請求的發送者和接收者解耦
* 簡化了對象。使得對象不需要知道鏈的結構。
* 增強給對象指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
* 增加新的請求處理類很方便。
責任鏈模式的缺點:
* 不能保證請求一定被接收。
* 系統性能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成循環調用。
* 可能不容易觀察運行時的特征,有礙于除錯。
今日推薦