JAVA架构师之路十五:设计模式之策略模式
责任链模式
- 1. 责任链模式
- 2. 登陆案例
- 3. 登陆案例优化
人生的游戏不在于拿了一副好牌,而在于怎样去打好坏牌,世上没有常胜将军,勇于超越自我者才能得到最后的奖杯。
1. 责任链模式
定义
责任链模式是将链中每一个节点看作是一个对象,每个节点请求处理的请i去均不同,且内部自动维护一个下一个节点对象。当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象。直至有对象处理这个请求为止。
属于行为型模式
适用场景
多个对象可以处理同一个请求,但具体由哪个对象处理,则在运行时动态决定。
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求
可动态指定一组对象处理请求。
优点
将请求与处理解耦
请求处理者(节点对象)只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一级节点对象;
具备链式传递处理请求功能,请求发送者无需知晓链路结构,只需等待请求处理结果
链路结构灵活,可以通过改变连句结构动态地新增或者删见责任;
易于扩展新的请求处理类(节点),符合开闭原则
缺点
责任链太长或者处理时间过长,会影响整体性能
如果节点对象存在循环引用时,会造成死循环,导致系统崩溃
2. 登陆案例
大部分的网站都需要登陆,一般的登陆流程都需要先校验输入的用户名密码是否合法,再者校验用户是否存在,然后再校验权限等等。
public abstract class Handler {protected Handler next;public void next(Handler next) {this.next = next;}public abstract void doHandler(Member member);}
public class ValidateHandler extends Handler {@Overridepublic void doHandler(Member member) {if (StringUtils.isBlank(member.getLoginName()) || StringUtils.isBlank(member.getLoginPass())) {System.out.println("用户名或者密码为空!");return;}System.out.println("用户名密码不为空,可以往下执行");next.doHandler(member);}
}
public class LoginHandler extends Handler {@Overridepublic void doHandler(Member member) {System.out.println("登陆成功");member.setRoleName("管理员");next.doHandler(member);}
}
public class AuthHandler extends Handler {@Overridepublic void doHandler(Member member) {if(!"管理员".equals(member.getRoleName())) {System.out.println("您不是管理员,没有操作权限");return;}System.out.println("允许操作");}
}
public class MemberService {public void login(String loginName, String loginPass) {ValidateHandler validateHandler = new ValidateHandler();LoginHandler loginHandler = new LoginHandler();AuthHandler authHandler = new AuthHandler();validateHandler.next(loginHandler);loginHandler.next(authHandler);validateHandler.doHandler(new Member(loginName, loginPass));}
}
public class Test {public static void main(String[] args) {MemberService memberService = new MemberService();memberService.login("tom", "123456");memberService.login("tom", null);}
}
用户名密码不为空,可以往下执行
登陆成功
允许操作
用户名或者密码为空!
3. 登陆案例优化
在MemberService
中有一些validateHandler.next(loginHandler);loginHandler.next(authHandler);
的操作,这样其实很烦,因为你必须要知道上下文才能把整个链路串起来,那么想到以前的Builder
模式,可以优化一下:
public abstract class Handler {protected Handler next;public void next(Handler next) {this.next = next;}public abstract void doHandler(Member member);public static class Builder {private Handler head;private Handler tail;public Builder 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 build(){return this.head;}}
}
public class MemberService {public void login(String loginName, String loginPass) {Handler.Builder builder = new Handler.Builder();builder.addHandler(new ValidateHandler()).addHandler(new LoginHandler()).addHandler(new AuthHandler());builder.build().doHandler(new Member(loginName, loginPass));}
}
内部维护一个链路,只需要调用add
方法就能往里面添加链路了。
感谢您阅读本文,如果您觉得文章写的对您有用的话,请您点击上面的“关注”,点个赞,这样您就可以持续收到《JAVA架构师之路》的最新文章了。文章内容属于自己的一点点心得,难免有不对的地方,欢迎在下方评论区探讨,你们的关注是我创作优质文章的动力。