当前位置: 首页 > 后端技术 > Java

这是责任链模式的优雅使用方法

时间:2023-04-01 16:30:36 Java

1 使用责任链模式设计可热插拔的权限控制publicclassMember{privateStringloginName;私人字符串登录密码;私有字符串角色名;publicMember(StringloginName,StringloginPass){this.loginName=loginName;this.loginPass=登录密码;StringgetLoginPass(){返回登录密码;}publicStringgetRoleName(){返回角色名;}publicvoidsetRoleName(StringroleName){this.roleName=roleName;}@OverridepublicStringtoString(){return"Member{"+"loginName='"+loginName+'\''+",loginPass='"+loginPass+'\''+'}';}}然后我们来看一段我们经常写的代码。publicclassMemberService{publicvoidlogin(StringloginName,StringloginPass){if(StringUtils.isEmpty(loginName)||StringUtils.isEmpty(loginPass)){System.out.println("用户名密码验证成功,可以下去执行");返回;}System.out.println("用户名和密码不为空,可以继续执行");会员member=checkExists(loginName,loginPass);如果(null==成员){System.out。println("用户不存在");返回;}System.out.println("登录成功!");if(!"Administrator".equals(member.getRoleName())){System.out.println("您不是管理员,没有操作权限");返回;}System.out.println("允许运行");}privateMembercheckExists(StringloginName,StringloginPass){Membermember=newMember(loginName,loginPass);成员.setRoleName("管理员");回归会员;}publicstaticvoidmain(String[]args){MemberServiceservice=newMemberService();服务.登录(“到m","666");}}上面代码中主要是做登录前的数据校验,判断逻辑是时序的,先做非空判断,再判断账号是否有效,最后获取用户角色,根据用户角色拥有的权限匹配是否有操作权限,那么这样的检查代码一般是必不可少的,但是写在具体的业务代码中就很臃肿,所以可以使用责任链model将这些检查步骤串联起来,在不影响代码美观的情况下,可以让我们在编码的时候更加专注于一个具体的业务逻辑处理。接下来,使用责任链模型对代码进行优化。首先,创建一个Handler类.publicabstractclassHandler{protectedHandlerchain;publicvoidnext(Handlerhandler){this.chain=handler;}publicabstractvoiddoHandle(Membermember);}然后创建非空验证ValidateHandler类,登录验证LoginHandler类和权限分别验证AuthHandler类。ValidateHandler类代码如下。publicclassValidateHandlerextendsHandler{publicvoiddoHandle(Membermember){if(StringUtils.isEmpty(member.getLoginName())||StringUtils.isEmpty(member.getLoginPass())){System.out.println("用户名或密码为空");返回;}System.out.println("用户名密码验证成功,可以继续执行");chain.doHandle(成员);}}LoginHandler类的代码如下。publicclassLoginHandlerextendsHandler{publicvoiddoHandle(Membermember){System.out.println("登录成功!");member.setRoleName("管理员");chain.doHandle(成员);}}AuthHandler类代码如下。publicclassAuthHandlerextendsHandler{publicvoiddoHandle(Membermember){if(!"Administrator".equals(member.getRoleName())){System.out.println("您不是管理员,没有权限操作");返回;}System.out.println("你是管理员,你可以操作");}}接下来修改MemberService中的代码。其实只需要将之前定义的Handlers按照业务需求连接起来就可以形成一条链。能。publicclassMemberService{publicvoidlogin(StringloginName,StringloginPass){HandlervalidateHandler=newValidateHandler();处理程序loginHandler=newLoginHandler();处理程序authHandler=newAuthHandler();validateHandler.next(loginHandler);授权处理程序);validateHandler.doHandle(新成员(登录名,登录密码));}}最后写客户端调用代码。公共类测试{publicstaticvoidmain(String[]args){MemberServiceservice=newMemberService();service.login("tom","666");}}运行结果如下图所示。其实我们平时使用的很多权限验证框架都是利用了这个原理。将各个维度的权限处理解耦后,串联起来,只处理各自的职责。如果责任与你无关,就丢给链条中的下一个Handler,俗称“踢球”。2 责任链模式和建造者模式结合使用是因为责任链模式具有链式结构,而在上面的代码中,负责组装链式结构的角色是MemberService。当链式结构较长时,MemberService的工作会很繁琐,而且MemberService的代码比较臃肿,而且后续改变处理器或消息类型时,必须在MemberService中修改,不符合开闭原则。出现这些问题的原因是链条结构的装配过于复杂。对于复杂结构的创建,我们自然会想到建造者模式。使用构建器模式,可以自动链接MemberService指定的处理节点对象。客户只需要指定处理节点对象,其他不需要关心,而且客户指定的处理节点对象顺序不同,构建的链结构也不同。我们来修改一下,先修改Handler的代码。公共抽象类Handler{受保护的处理程序链;publicvoidnext(Handlerhandler){this.chain=handler;}publicabstractvoiddoHandle(成员成员);publicstaticclassBuilder{privateHandlerhead;私人处理程序尾部;publicBuilderaddHandler(Handlerhandler){if(this.head==null){this.head=this.tail=handler;归还这个;}this.tail.next(handler);this.tail=处理程序;归还这个;}publicHandlerbuild(){returnthis.head;}}}然后修改MemberService的代码。publicclassMemberService{publicvoidlogin(StringloginName,StringloginPass){Handler.Builderbuilder=newHandler.Builder();builder.addHandler(newValidateHandler()).addHandler(newLoginHandler()).addHandler(newAuthHandler());builder.build().doHandle(新成员(loginName,loginPass));}}因为builder模式构建的是nodehandlers,所以我们使用Builder作为Handler的静态内部类,并且因为客户端不需要链式组装,所以也可以将链式组装方法next()方法设置为private,使处理程序更高度聚合。代码如下。公共抽象类Handler{受保护的处理程序链;privatevoidnext(Handlerhandler){this.chain=handler;}...}通过这个案例,小伙伴们应该感受到responsibilitychain和builderup相结合的精髓了。关注微信公众号『汤姆炸弹架构』回复“设计模式”获取完整源码。【推荐】汤姆炸弹架构:30个设计模式实战案例(附源码),挑战60W年薪不是梦技术在于分享,我分享我的快乐!如果本文对您有帮助,请关注并点赞;有什么建议也可以留言或私信。您的支持是我坚持创作的动力。关注微信公众号“汤姆炸弹建筑”,获取更多技术干货!