java23种设计模式(2)-责任链模式
最近在公司做业务,发现有一个很麻烦的事情。什么麻烦事呢。楼主遇到了,就说出来让大家开心一下。哈哈!
事情是这样的,在我公司的网上发布一条消息。需要进行如下的操作!
- 第一步:过滤所有的敏感词(部分词不方便发出来,以免和谐)。
- 第二步:看一下这个人今天发布了多少条消息!(一天以内有次数限制)
- 第三步:校验一下这人的手机号是不是敏感了(比如打不通,比如有人举报骚扰)
- 第四步:过滤一下用户的id黑名单
- 第五步:如果前面的都是满足我们的要求,保存这个用户的本条消息。
- 第六步: 做一些后续操作,比如推送呀
- 第七步: 同步到其他的业务方。
诸如此类吧!上面就是基本的流程了(当然很多公司都是很复杂的,不参与泄密哦)。我发现就有一个条是数据库插入其他都是一些查询和过滤。也就是最重要的是那条插入。当然不是说后续的不重要。
可是有个问题是,当我过滤这些条件的时候,我发现,我的if else 已经多到可怕了。就是一连串的if else。判断第一个然后一直到最后一个条件。有人可能会问能不能用 & 连起来所有的条件。其实,我也想了但是不行,因为比如过滤敏感词,只是把敏感词去除消息可以正常发的。不能返回一个false完事!说起来就是不太合适。
那我该怎么办呢???头大!
这个时候,今天的主角就要登场了。也就是责任链模式。
责任链模式,就是将这些我们要执行的一切东西都连成一个链这个可以是一个环也可以是一条直线。都可以的也就是图中所示的一样。
现在来说一下责任链的角色。抽象处理者(抽象接口)。具体处理者(每一个业务)。客户端调用方。
这个时候一般情况下每一个业务方,都应该有下一个业务方的对象才可以进入下一个业务方.
还是那句话, talk is cheap, show your code
package com.responsibility.simple;
/**
* 过滤接口,也就是抽象接口,具有一个处理的方法。
* */
public interface ITestFilter {
void handle(Object target,Object other);
}
package com.responsibility.simple;
import com.responsibility.filter.Filter;
import lombok.Data;
/**
* 这里需要提供是否进行下一个过滤器或者是职责链的方法!是一个用户继承对的抽象类
* 有人会觉得这个为什么要写一个接口然后再来一个抽象类这里是为了接口清晰只负责处理职责
* */
@Data
public abstract class TestFilter implements ITestFilter {
private ITestFilter nextHandler;
/**
* 继续过滤器链
*/
protected void next(){
this.filterResult = Filter.FilterResult.GO_NEXT;
}
/**
* 停止过滤器链
*/
protected void stop(){
this.filterResult = Filter.FilterResult.STOP;
}
/**
* 默认为继续接下来的过滤器
*/
private Filter.FilterResult filterResult = Filter.FilterResult.GO_NEXT;
public enum FilterResult{
STOP(-1), //停止过滤器链
GO_NEXT(0); //继续过滤器链
private int value = 0;
private FilterResult(int value){
this.value = value;
}
}
}
package com.responsibility.simple.example;
/**
* 这是一个简化版的过滤连
* */
public class Test {
public static void main(String[] args) {
BlackFilter blackFilter = new BlackFilter();
SentiveFilter sentiveFilter = new SentiveFilter();
InsertFilter insertFilter= new InsertFilter();
sentiveFilter.setNextHandler(insertFilter);
blackFilter.setNextHandler(sentiveFilter);
insertFilter.setNextHandler(null);
//从这一行往上都可以在初始化的时候做好这些工作,然后通过提供一个可以来调用,就是初始化一个过滤连然后就可以到处调用了!
Request request = new Request();
request.setName("abc");
blackFilter.handle(request,null);
}
}
package com.responsibility.simple.example;
import lombok.Data;
/**
* 要被处理的对象!
* */
@Data
public class Request {
private String name;
}
package com.responsibility.simple.example;
import com.responsibility.simple.TestFilter;
/**
* 具体的职责业务,可以向外暴露提供或者是由客户端自行编写,然后添加更加方便
* */
public class BlackFilter extends TestFilter {
@Override
public void handle(Object target, Object other) {
if(target instanceof Request){
Request request = (Request) target;
if(request.getName().equals("black")){
System.out.println("黑户不能发消息!");
if(null == getNextHandler()){
System.out.println("处理完毕!");
}
stop();
}else {
System.out.println("不是黑户!");
if(null == getNextHandler()){
System.out.println("处理完毕!");
}else {
getNextHandler().handle(target, other);
}
}
}
}
}
还有两个业务的实现类都是例子就不粘贴了。
下面我们来说说这个责任链模式的另外的事情。职责连模式,有什么好处。
- 先后顺序随意可变只要去设置下一个处理的对象。
- 不需要和所有的所有的过滤耦合
可以冲任何一关开始这个需要一个参数就可以搞定。例子中的other就是用来干这个的。
最后题中的责任链模式是一个纯责任链,那什么叫做纯责任链模式呢?
- 纯责任链模式,对一个个责任,不是承担,就是给下家。不出现只处理一部分责任,然后给下家。
- 不纯责任链模式,可以承担部分责任。比如我们申请一个几日预算,组长批100块经理批900加起来1000。
纯责任链一定会有对象接收要处理的对象。但是不纯的就可以五对象接受。
老规矩附上代码的github地址:
https://github.com/yunzhifei/designPatterns.git
欢迎转载, 转载请保留原文出处,谢谢配合!