从 UML类图中,我们可以看到,责任链模式主要包含两种角色:
抽象处理者(Handler):定义一个请求处理的方法,并维护一个下一个处理节点Handler对象的
引用;
具体处理者(ConcreteHandler):对请求进行处理,如果不感兴趣,则进行转发。
责任链模式的本质是解耦请求与处理,让请求在处理链中能进行传递与被处理;理解责任链模式应
当理解的是其模式(道 )而不是其具体实现(术 ),责任链模式的独到之处是其将节点处理者组合成了
链式结构,并允许节点自身决定是否进行请求处理或转发,相当于让请求流动了起来。
利用责任链模式进行数据校验拦截
首 先, 创建一个实体类Member :
@Data public class Member { private String loginName; private String loginPass; private String roleName; public Member(String loginName, String loginPass) { this.loginName = loginName; this.loginPass = loginPass; } }
然后来看一段我们经常写的代码:
public class MemberService { public static void main(String[] args) { MemberService service = new MemberService(); service.login("tom", "666"); } public void login(String loginName, String loginPass) { if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(loginPass)) { System.out.println("用户名和密码为空"); return; } System.out.println("用户名和密码不为空,可以往下执行"); Member member = checkExists(loginName, loginPass); if (null == member) { System.out.println("用户不存在"); return; } System.out.println("登录成功!"); if (!"管理员".equals(member.getRoleName())) { System.out.println("您不是管理员,没有操作权限"); return; } System.out.println("允许操作"); } private Member checkExists(String loginName, String loginPass) { Member member = new Member(loginName, loginPass); member.setRoleName("管理员"); return member; } }
请问各位小伙伴,你们是不是经常这么干?上面的代码中,主要功能是做了登录前的数据验证,然
后
, 判断逻辑是有先后顺序的。首先做非空判断,然后检查账号是否有效,最终获得用户角色。然后根
据用户角色所拥有的权限再匹配是否有操作权限。那么这样的检验性代码一般都是必不可少的
, 但是写在具体的业务代码又显得代码非常臃肿,因此我们可以用责任链模式
, 将这些检查步骤串联起来,而且
不影响代码美观。可以使得我们在编码时可以更加专注于某一个具体的业务逻辑处理。
下面我们用责任链模式来优化一下代码,首先创建一个Handler类 :
public abstract class Handler { protected Handler next; public void next(Handler next){ this.next = next;} public abstract void doHandler(Member member); }
我们分别创建非空校验ValidateHandler类、登录校验LoginHandler类和权限校验AuthHandler
类 ,来看代码ValidateHandler类 :
public class ValidateHandler extends Handler { public void doHandler(Member member) { if (StringUtils.isEmpty(member.getLoginName()) || StringUtils.isEmpty(member.getLoginPass())) { System.out.println("用户名和密码为空"); return; } System.out.println("用户名和密码不为空,可以往下执行"); next.doHandler(member); } }
LoginHandler 类:
public class LoginHandler extends Handler { public void doHandler(Member member) { System.out.println("登录成功!"); member.setRoleName("管理员"); next.doHandler(member); } }
AuthHandler 类:
public class AuthHandler extends Handler { public void doHandler(Member member) { if (!"管理员".equals(member.getRoleName())) { System.out.println("您不是管理员,没有操作权限"); return; } System.out.println("允许操作"); } }
接下来,修 改Memberservice中的代码,其实我们只需要将前面定义好的几个Handler根据业务需求串联起来,形成一条链即可
public class MemberService { public void login(String loginName, String loginPass) { Handler validateHandler = new ValidateHandler(); Handler loginHandler = new LoginHandler(); Handler authHandler = new AuthHandler(); validateHandler.next(loginHandler); loginHandler.next(authHandler); validateHandler.doHandler(new Member(loginName, loginPass)); } }