策略模式和责任链模式(4)

策略模式和责任链模式(4)


从 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));
    }
}
上一篇:Docker——Docker环境的搭建(二)(1)


下一篇:委派模式与模板模式(5)