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

相关文章
|
4月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
486 2
|
4月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
425 0
|
6月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
4月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
530 35
|
4月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
400 8
|
9月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
195 0
|
5月前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
6月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
6月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
12月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
262 13
「全网最细 + 实战源码案例」设计模式——责任链模式