首页 > 其他分享 >构造模式+责任链模式实现链式调用(可以用于参数校验等)

构造模式+责任链模式实现链式调用(可以用于参数校验等)

时间:2023-07-06 23:34:42浏览次数:42  
标签:return 校验 模式 next Handler 链式 programmer doHandler public

参考:https://zhuanlan.zhihu.com/p/553917078?utm_id=0
一、责任链模式
责任链模式(Chain of Responsibility Pattern)是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。属于行为型模式。
二、责任链模式的优缺点
1、优点
减少大量ifelse;
逻辑清晰明了,添加删除节点、改变节点顺序方便快捷;
请求与处理解耦;
请求处理者只需关注自己感兴趣的请求,对于不感兴趣的请求,直接转发给下一级节点对象;
易于扩展新的请求处理类,符合开闭原则;
2、缺点
责任链太长或处理时间过长,会影响整体性能。
如果需要判断的东西较多,容易造成类保证;
如果每个判断逻辑较简单,可能会造成一个类只做一个小小的数值判断,哈哈;
如果节点对象存在循环链接,可能会造成死循环;
三、实践
传统方法

@Data
public class Programmer {
    // 姓名
    private String name;
    // 项目
    private String project;
    // 模块
    private String module;
    // 进度
    private double schedule;
    // 计划完成时间
    private Date completePlanTime;
    // 详细信息
    private String info;
}
public class Check {

    public boolean programmerCheck(Programmer programmer){

        if(!"公众号".equals(programmer.getProject())){
            return false;
        }

        if(!"哪吒编程".equals(programmer.getName())){
            return false;
        }

        if(!programmer.getInfo().equals("公众号哪吒编程,定期分享Java干货,还有不定期的送书活动,包邮到你家,哈哈")){
            return false;
        }

        return true;
    }
}

通过责任链模式重构代码
1、链路抽象类定义
这部分是责任链模式的核心代码,重点在于通过next获取下一个节点。

定义一个抽象方法doHandler供子类去实现,实现不同的业务逻辑

public abstract class Handler<T> {

    protected Handler next;

    private void next(Handler next) {
        this.next = next;
    }

    public abstract boolean doHandler(Programmer programmer);

    public static class Builder<T> {
        private Handler<T> head;
        private Handler<T> tail;

        public Builder<T> addHandler(Handler handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return this;
        }

        public Handler<T> build() {
            return this.head;
        }
    }
}

(1)项目名称检验

/**
 * 校验项目名称
 */
public class ProjectHandler extends Handler {

    @Override
    public boolean doHandler(Programmer programmer) {

        if(!"公众号".equals(programmer.getProject())){
            return false;
        }

        if(null == next){
            return true;
        }

        return next.doHandler(programmer);
    }
}

校验名字

/**
 * 校验名字
 */
public class NameHandler extends Handler {

    @Override
    public boolean doHandler(Programmer programmer) {

        if(!"哪吒编程".equals(programmer.getName())){
            return false;
        }

        if(null == next){
            return true;
        }

        return next.doHandler(programmer);
    }
}

校验活动细节

/**
 * 校验活动细节
 */
public class InfoHandler extends Handler {

    @Override
    public boolean doHandler(Programmer programmer) {

        if(!programmer.getInfo().contains("扫描文末二维码,关注公众号哪吒编程,定期分享Java干货,还有不定期的送书活动,包邮到你家")){
            return false;
        }

        if(null == next){
            return true;
        }

        return next.doHandler(programmer);
    }
}

测试

核心代码流程:

调用流程:
(1)new Hadnler.Builder() 构建Builder类对象
(2)addHandler(new ProjectHandler()) 此时this.head为空。this.head 和this.tail的地址指向 new ProjectHandler()的地址
(3)addHandler(new NameHandler()) 此时的this.head不为空,走下面,this.tail.next指向NameHandler。因为(2)的this.head = this.tail,此时的是引用传递,传递的是内存地址。所以内存地址的next为NameHandler,所以this.head的next为NamHandler。然后this.tail的地址指向NameHandler的地址
(4)addHandler(new InfoHandler())此时this.tail指向NameHandler。他的next指向InfoHandler,所以NameHandler的next指向InfoHandler。然后将他指向InfoHandler
(5)build 获得this.head,然后doHandler()处理,里面的next.doHandler调用NameHandler处理,依次.....

标签:return,校验,模式,next,Handler,链式,programmer,doHandler,public
From: https://www.cnblogs.com/cgy1995/p/17533614.html

相关文章

  • 关于几个结构型模式的讨论
    结构型模式的思路是组合,而根据组合侧重的不同方面,分为了不同的模式。结构型模式的思路和行为型模式中的模板方法模式有一定相似性,尤其是在实现具体的函数时,不过不同之处在于模板方法模式采用的是继承,并且它们的目的也不一样,结构型模式的目的是扩展、增减功能,而模板方法模式的目......
  • JAVA设计模式之原型模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • JavaScript校验地图经纬度是否符合规范
    functionverifylonglat(longitude,latitude){varlongreg=/^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,6})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/;if(!longreg.test(longitude)){returnnewError('经度,整数部分为0-180小数部分为......
  • 淘宝技术三面题目:分布式架构+红黑树+SpringMVC+设计模式
     淘宝一面Java容器有哪些?哪些是同步容器,哪些是并发容器?ArrayList和LinkedList的插入和访问的时间复杂度?java反射原理,注解原理?新生代分为几个区?使用什么算法进行垃圾回收?为什么使用这个算法?HashMap在什么情况下会扩容,或者有哪些操作会导致扩容?HashMappush方法的执行过......
  • Day14-设计模式之迭代器模式
    设计模式之迭代器模式一、概念定义:提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构意图:如果我们的集合元素是用不同方式实现的,有数组、集合或者其他方式。当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而......
  • Day13-设计模式之访问者模式
    设计模式之访问者模式一、概念定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。模式动机:对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问......
  • Day10-设计模式之外观模式
    设计模式之外观模式一、引例当我们现在想要在家通过投影仪看电影,其过程包括关灯,关闭窗帘,打开投影仪,这些家居都是独立的,就会有灯光开关、窗帘开关、投影仪开关。我们需要一步一步的去打开这些开关。如果用代码来实现,就可将灯光,窗帘等都看成一个对象,然后用Client端依次去调用这些......
  • Day11-设计模式之享元模式
    设计模式之享元模式一、意图在面向对象系统的设计和实现中,创建对象是最为常见的操作。这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销。特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可......
  • Day13-设计模式之命令模式
    设计模式之命令模式一、引例我们买了一套智能家电,有照明灯、风扇、冰箱、洗衣机,我们只要在手机上安装app就可以控制对这些家电工作。这些智能家电来自不同的厂家,我们不想对每一种家电都安装一个App,分别控制,我们希望只要一个app就可以控制全部智能家电。要实现一个app控制所......
  • Day12-设计模式之备忘录模式
    设计模式之备忘录模式一、引例案例引入游戏角色状态恢复问题游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态。传统的设计方案传统的方式的问题分析一个对象,就对应一个保存对象状态......