Java設計模式之責任鏈模式

生產一個產品,需要依次執行多個步驟,才能完成,那麼是使用責任鏈模式則是極好的。 在性能告警模塊開發過程中,創建一條告警規則需要執行閾值解析,中間表生成,流任務生成,規則入庫,告警事件入庫等諸多操作。如果把這些步驟糅合在一個類中,代碼可讀性及複雜度往往是災難的,特別對於這麼多步驟的事務性操作,更是力不從心。使用責任鏈模式,上述問題迎刃而解。 以告警規則創建爲例子,簡化流程如下 **閾值解析 ---> 流任務生成 ---> 規則入庫** 回滾流程如下 1、 閾值解析失敗:回滾閾值解析。 2、 流任務生產失敗:回滾流任務生成,閾值解析。 3、 規則入庫失敗:回滾規則入庫,流任務生成,閾值解析。 採用責任鏈模式編碼,思路如下: 1、 編寫閾值解析處理器,流任務生成處理器,規則入庫處理器,每個處理器包含業務處理方法和回滾方法; 2、 一個處理器業務代碼執行完成後主動調用下一個處理器業務方法; 3、 一個處理器業務代碼執行失敗主動調用本處理器回滾方法,本處理器回滾完成後主動調用上一個處理器回滾方法。 代碼如下 1、 抽象處理器 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; /** * * AbstractRuleHandler.java Create on 2017年5月5日 下午11:20:15 * * 類功能說明: 告警規則責任鏈處理節點抽象類 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public abstract class AbstractRuleHandler { // 上一個處理器 private AbstractRuleHandler preHandler; // 下一個處理器 private AbstractRuleHandler nextHandler; /** * 業務執行 * * @author coshaho * @param rule */ public void doHandle(AlarmRule rule) { try { doHandleReal(rule); } catch(Exception e) { // 業務代碼執行失敗主動回滾 rollBack(rule); return; } // 業務代碼執行成功主動調用下一個處理器處理 if(null != nextHandler) { nextHandler.doHandle(rule); } } /** * 事務回滾 * * @author coshaho * @param rule */ public void rollBack(AlarmRule rule) { rollBackReal(rule); // 本處理器業務回滾完成,主動調用前一個處理器業務回滾 if(null != preHandler) { preHandler.rollBack(rule); } } /** * 每個處理器特有的業務處理方法 * * @author coshaho * @param rule * @throws Exception */ public abstract void doHandleReal(AlarmRule rule) throws Exception; /** * 每個處理器特有的業務回滾方法 * * @author coshaho * @param rule */ public abstract void rollBackReal(AlarmRule rule); private AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) { this.preHandler = preHandler; return preHandler; } public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) { this.nextHandler = nextHandler; nextHandler.setPreHandler(this); return nextHandler; } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 2、閾值解析處理器 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * ThresholdParseHandler.java Create on 2017年5月5日 下午11:41:20 * * 類功能說明: 閾值解析 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class ThresholdParseHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getThreshold())) { throw new Exception("Threshold is empty."); } System.out.println("Parse threshold success. Threshold is " + rule.getThreshold()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll parse threshold. Threshold is " + rule.getThreshold()); } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 3、流任務生成處理器 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; /** * * StreamGenerateHandler.java Create on 2017年5月5日 下午11:41:43 * * 類功能說明: 告警流規則生成 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class StreamGenerateHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { System.out.println("Generate stream success."); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll Generate stream."); } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 4、規則入庫處理器 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 類功能說明: 告警規則持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 5、規則入庫處理器 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; import org.apache.commons.lang.StringUtils; /** * * RulePesistHandler.java Create on 2017年5月5日 下午11:41:08 * * 類功能說明: 告警規則持久化 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class RulePesistHandler extends AbstractRuleHandler { @Override public void doHandleReal(AlarmRule rule) throws Exception { if(StringUtils.isEmpty(rule.getName())) { throw new Exception("Rule name is empty."); } System.out.println("Persist rule success. Rule name is " + rule.getName()); } @Override public void rollBackReal(AlarmRule rule) { System.out.println("Roll persist rule. Rule name is " + rule.getName()); } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 6、告警規則 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; /** * * AlarmRule.java Create on 2017年5月5日 下午11:40:50 * * 類功能說明: 告警規則 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRule { private String name; private String type; private String threshold; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getThreshold() { return threshold; } public void setThreshold(String threshold) { this.threshold = threshold; } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 7、規則創建責任鏈 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript package com.coshaho.learn.handler; /** * * AlarmRuleCreator.java Create on 2017年5月5日 下午11:56:45 * * 類功能說明: 告警規則創建 * * Copyright: Copyright(c) 2013 * Company: COSHAHO * @Version 1.0 * @Author coshaho */ public class AlarmRuleCreator { private AbstractRuleHandler alarmRuleHandler; public AlarmRuleCreator() { alarmRuleHandler = new ThresholdParseHandler(); alarmRuleHandler.setNextHandler(new StreamGenerateHandler()) .setNextHandler(new RulePesistHandler()); } public void create(AlarmRule rule) { alarmRuleHandler.doHandle(rule); } public static void main(String[] args) { AlarmRule rule = new AlarmRule(); rule.setThreshold("cpuRate < 10"); rule.setName("Cpu Alarm"); AlarmRuleCreator ruleCreator = new AlarmRuleCreator(); ruleCreator.create(rule); System.out.println(); rule.setName(""); ruleCreator.create(rule); } } ``` ![](https://common.cnblogs.com/images/copycode.gif) 測試結果 ![](https://common.cnblogs.com/images/copycode.gif) ```javascript Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Persist rule success. Rule name is Cpu Alarm Parse threshold success. Threshold is cpuRate < 10 Generate stream success. Roll persist rule. Rule name is Roll Generate stream. Roll parse threshold. Threshold is cpuRate < 10 ``` ![](https://common.cnblogs.com/images/copycode.gif)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章