.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}
大家好,我是练习java两年半时间的南橘,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助
有需要的同学可以加我的公众号,以后的最新的文章第一时间都在里面,也可以找我要思维导图
【进阶之路】理解结构型模式开发(桥接模式) 【进阶之路】理解结构型模式开发(享元模式) 【进阶之路】理解结构型模式开发(适配器模式)
之前和大家分享了设计模式中的结构型模式,它主要是描述如何将类或对象通过组合新来实现功能,而我也是挑选了结构型模式中一些新接触设计模式的同学们不太能注意到的与大家分享(像代理模式、装饰模式等都是平常学习中接触较多的)。分享的初衷也是自己在工作中灵光一现发现可以用这种模式来提高效率(特指桥接模式)。
那么这次,我准备和大家分享行为型模式中的责任链模式。
初衷也是我在完成需求的时候,碰巧研究了一下自己的代码,发现用到了过滤器模式和责任链模式(过滤器模式其实在标准的API文档里没有找到,但是网上也有介绍这个)。
责任链模式的定义
为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
在责任链模式中,我们只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。
责任链模式的优点:
责任链模式的缺点:
职责链模式主要角色:
抽象处理者角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
根据路由选择器的过滤器模式+责任链模式,我们这边首先实现过滤连,将过滤器组装进来。
我们代码实现一次简单的过滤,过滤条件大概是是否能获得北京某借贷公司发放给本地人的小额贷款。
每个各司其职的Filter都有可能被执行,我们可以将其串成一条链
public class FilterChain {
@Autowired
private List filters;
public FilterChain() {
filters =new ArrayList<>();
System.out.println("过滤器链路初始化.....");
filters.add(new AgeFilter());
filters.add(new hukouFilter());
filters.add(new IncomeFilter());
System.out.println("过滤器链路加载完毕.....");
}
//轮询调用已加载的过滤器
public void processData(UserInfo data) {
for (Filter filter : filters) {
boolean b = filter.doFilter(data);
if (!b){
break;
}
}
}
}
public interface Filter {
// 过滤器处理
boolean doFilter(UserInfo data);
}
public class AgeFilter implements Filter {
public AgeFilter() {
System.out.println("年龄过滤器加载");
}
@Override
public boolean doFilter(UserInfo data) {
System.out.println("年龄风控拦截......");
if (data.getAge()<18){
System.out.println(data.getName()+"年龄低于18岁");
return false;
}
return true;
}
}
public class hukouFilter implements Filter {
public hukouFilter() {
System.out.println("户口过滤器加载");
}
@Override
public boolean doFilter(UserInfo data) {
System.out.println("户口拦截判断......");
if ("北京".equals(data.getHukou())){
return true;
}
System.out.println(data.getName()+"不是北京户口,无法借款");
return false;
}
}
public class IncomeFilter implements Filter {
public IncomeFilter() {
System.out.println("收入过滤器加载");
}
@Override
public boolean doFilter(UserInfo data) {
System.out.println("收入风控拦截......");
if (data.getIncome()<100000) {
if ("北京".equals(data.getHukou())) {
System.out.println(data.getName() + "年收入低于10w,但是是北京户口,给予通过");
return true;
}
System.out.println(data.getName() + "年收入低于10w");
return false;
}
return true;
}
}
public class UserInfo {
private String name;
private Integer age;
private Integer income;
private String hukou;
public UserInfo(Integer age, Integer income, String hukou,String name) {
this.age = age;
this.income = income;
this.hukou = hukou;
this.name =name;
}
}
public static void main(String[] args) {
UserInfo personA =new UserInfo(32,200000,"湘西", "小林");
UserInfo personB =new UserInfo(22,90000,"北京","小罗");
FilterChain f =new FilterChain();
f.processData(personA);
f.processData(personB);
}
我们在很多地方都能看到这样的责任链模式,那么我是你要这样干?如果想要便捷的话,不如直接增加一个if,一个处理方法来得方便。
没错,但是遇上代码量大,链路长,甚至有几十层过滤器的时候,责任链分工明确,解耦,容易维护的好处就体现出来了。
除了过滤器这里,在实际开发中,各种路由的选择也通常需要依靠责任链模式来实现,比如说网上比较火的小贷。许多银行都有提供贷款的业务,如果同时有多个贷款业务在运转中的话,用户申请贷款的时候系统会在后台走一遍资金路由的流程,最后选择用户最适合的产品给用户开通。
当然,除了这样的设计,责任链模式还有一种玩法,就是分段处理模式。一个用户如果需要被处理的内容特别多,为了尽量不违反单一职责原则和接口隔离原则,可以将这些处理类也用责任链的方式串联起来,每一个处理类处理一部分的内容,等责任链走完后,自然也就处理完毕了。
当然,这样也可能遇到新的问题,比如处理到一半突然系统出错了之类的。需要这样处理的话,也可以充分的利用幂等性原则,将状态储存下来,等问题修复后从出错的地方再次处理。