Java设计模式之责任链模式
2019年阿里云双11活动拼团:https://www.aliyun.com/1111/2019/group-buying-share
生产一个产品,需要依次执行多个步骤,才能完成,那么是使用责任链模式则是极好的。
在性能告警模块开发过程中,创建一条告警规则需要执行阈值解析,中间表生成,流任务生成,规则入库,告警事件入库等诸多操作。如果把这些步骤糅合在一个类中,代码可读性及复杂度往往是灾难的,特别对于这么多步骤的事务性操作,更是力不从心。使用责任链模式,上述问题迎刃而解。
以告警规则创建为例子,简化流程如下
阈值解析 ---> 流任务生成 ---> 规则入库
回滚流程如下
1、 阈值解析失败:回滚阈值解析。
2、 流任务生产失败:回滚流任务生成,阈值解析。
3、 规则入库失败:回滚规则入库,流任务生成,阈值解析。
采用责任链模式编码,思路如下:
1、 编写阈值解析处理器,流任务生成处理器,规则入库处理器,每个处理器包含业务处理方法和回滚方法;
2、 一个处理器业务代码执行完成后主动调用下一个处理器业务方法;
3、 一个处理器业务代码执行失败主动调用本处理器回滚方法,本处理器回滚完成后主动调用上一个处理器回滚方法。
代码如下
1、 抽象处理器
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;
}
}
2、阈值解析处理器
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());
}
}
3、流任务生成处理器
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.");
}
}
4、规则入库处理器
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());
}
}
5、规则入库处理器
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());
}
}
6、告警规则
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;
}
}
7、规则创建责任链
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);
}
}
测试结果
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

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
TDD的测试周期
测试驱动开发的编写周期 (简单的总体把握) 应该知道,没有测试,就没有功能代码。测试驱动开发这种编程方式怎么开始呢,那就是先写一个新的测试 梗概如下: 添加一个测试; /** 要明白,现在这个测试里所用到的类和方法都是不存在的。此时的测试甚至是编译无法通过! */ @Test public void testMovieRating() { Movie starWars = new Movie("Star Wars"); starWars.addRating(3); starWars.addRating(5); assertEquals("Bad average rating", 4, starWars.getAverageRating()); } 运行所有的测试并查看失败的; /** 通过运行所有的测试,我们将会收到错误的信息提示,告诉了我们现在测试中存在的问题。可想见如下: 1.不存在Movie类 2.不存在addRating() 3.不存在getAverageRating() 如何解决?很简单,按照提示,利用开发环境(编译器如IDea)的强大功能迅速创建一个Movie类、方法。 *...
-
下一篇
JAVA设计模式(1)工厂模式
JAVA设计模式之工厂模式—Factory Pattern 1.工厂模式简介 工厂模式用于对象的创建,使得客户从具体的产品对象中被解耦。 2.工厂模式分类 这里以制造coffee的例子开始工厂模式设计之旅。 我们知道coffee只是一种泛举,在点购咖啡时需要指定具体的咖啡种类:美式咖啡、卡布奇诺、拿铁等等。 /** * * 拿铁、美式咖啡、卡布奇诺等均为咖啡家族的一种产品 * 咖啡则作为一种抽象概念 * @author Lsj * */ public abstract class Coffee { /** * 获取coffee名称 * @return */ public abstract String getName(); } /** * 美式咖啡 * @author Lsj * */ public class Americano extends Coffee { @Override public String getName() { return "美式咖啡"; } } /** * 卡布奇诺 * @author Lsj * */ public class Cappuccino ext...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS关闭SELinux安全模块