设计模式责任链模式——过滤器案例

Posted 叁滴水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式责任链模式——过滤器案例相关的知识,希望对你有一定的参考价值。

文章目录

背景需求

        笔者经历过一次道闸功能的实现,多种多样的道闸规则,加上每天都在新增的过滤规则让我和是头疼。拿最近疫情期间部分地区的道闸规则为例。

规则可能如下:

拥有24小时核酸的开闸

拥有48小时核酸的开闸

拥有72小时核酸+核酸检测中记录的开闸

也许这时我们只需要简单一个if/else就可以搞定。

public Boolean checkOpenDoor(User user)
    if(是否有24小时核酸)
    	return true;
    
    if(是否有48小时核酸)
    	return true;
    
    if(是否有72小时核酸+核酸检测中记录)
    	return true;
    
    return false;


如果再加几个规则呢?

白名单24小时随时开闸

黑名单不开闸

普通人员早上8点-9点开闸

普通人员在下班期间要求48小时核酸开闸

普通人员上班期间要求24小时核酸开闸

等等

        随着越来越多的规则加入,规则之间可能也会有权重、顺序等概念,简单的if/else也许就无法写出高质量的代码,并且真实情况下,业务会更加复杂,这样维护的成本会越来越高。

优化思路

        我们可以将每一个开门条件看成一个规则,将多个规则链接起来实现一个规则过滤器链。

如上图所示,乍一看跟Servlet Filter及其相似,附上Filter的流程图。

        由此看来,代码的结构就清晰了,将每个规则都定义一个类,每个类认为是一个规则,将这些类连接起来,形成规则过滤器,这就是设计模式——责任链模式。

责任链模式

        责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

        在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

通过责任链模式实现道闸开门规则验证。

定义抽象类,

public abstract class RuleCheck
    // 指向下一个规则,这里指定next不能为空,因此构造方法必须要填写下一个规则信息。
    public final RuleCheck next;

    protected RuleCheck(RuleCheck next) 
        this.next = next;
    
	 // 当前规则验证
    public abstract Boolean check(String user);



        每个新加的规则都新建一个类,并且继承这个抽象类,从而实现一个规则过滤链。如:

// 定义规则1
public class RuleCheck1 extends RuleCheck
    protected RuleCheck1(RuleCheck next) 
        super(next);
    

    @Override
    public Boolean check(String user) 
        // 判断不能为空
        if(user.isEmpty())
            return false;
        
        return next!=null?next.check(user):true;
    

// 定义规则2
public class RuleCheck2 extends RuleCheck
    protected RuleCheck2(RuleCheck next) 
        super(next);
    

    @Override
    public Boolean check(String user) 
        // 判断长度大于5
        if(user.length()>5)
            return false;
        
        return next!=null?next.check(user):true;
    

定义Start进行测试

    public static void main(String[] args) 
     	//定义规则过滤链
        RuleCheck ruleCheck2 = new RuleCheck2(null);
        RuleCheck ruleCheck1 = new RuleCheck1(ruleCheck2);
		
        // 验证用户1234567
        System.out.println(ruleCheck1.check("1234567"));
        // 验证用户1
        System.out.println(ruleCheck1.check("1"));
    

输出如下:

false
true

        如上,我只是简单展示了一下责任链模式的雏形,他的核心思想既是如此。在真实场景中要切勿生搬硬套,要做到灵活运用。才能达到其效果。

        本文中拿道闸为例,在真实的情况中各种各样的场景,都可以参考此思路,如电商活动权限验证、银行贷款身份信息验证等等。

以上是关于设计模式责任链模式——过滤器案例的主要内容,如果未能解决你的问题,请参考以下文章

设计模式责任链模式——过滤器案例

设计模式----责任链模式

设计模式责任链模式

责任链模式

Java责任链模式之总有你想不到的知识

设计模式之责任链模式