美文网首页
责任链模式

责任链模式

作者: yangzai | 来源:发表于2018-01-27 12:04 被阅读25次
  • 定义:
    在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

  • UML:

    • 时序图: image.png
    • 从上图我们可以看到,客户端首先创建了2个处理器ConcreteHandler,然后通过setSuccessor设置了第一个处理器的下一个处理器。然后客户端发送请求,先由第一个处理器处理,如果处理不了,再由第二个处理器处理。这样就形成了一条处理请求的链条。
    • 类图: image.png
  • 模型:公司购买请求决策
    公司内有很多职位,每个职位对采购设备金额的权限都不相同,例如组长、部门长、副总、总裁等职位。小金额的组长部门可以决定,大金额的则要上报副总或总裁。

根据UML图,我们首先要抽象出一个决策人类.这个对象抽象出处理请求的方法跟设置下一个决策人的方法
抽象决策人:

public abstract class Approver {
     Approver successor;
     String Name;
    public Approver(String Name){
        this.Name=Name;
    }
    public abstract void ProcessRequest( PurchaseRequest request);
    public void SetSuccessor(Approver successor) {
        this.successor=successor;
    }
}

组长:

public class GroupApprover extends Approver {
    public GroupApprover(String Name) {
        super(Name+" GroupLeader");     
    }
    //处理请求
    @Override
    public void ProcessRequest(PurchaseRequest request) {
        if (request.GetSum() < 5000) {//满足一定条件才自己处理,否则交给下一个处理器
            System.out.println("**This request " + request.GetID() + " will be handled by " + this.Name + " **");
        } else {
            //交给下一个处理器
            successor.ProcessRequest(request);
        }
    }
}

部门长:

public class DepartmentApprover extends Approver {
    public DepartmentApprover(String Name) {
        super(Name + " DepartmentLeader");
    }
    @Override
    public void ProcessRequest(PurchaseRequest request) {
        if ((5000 <= request.GetSum()) && (request.GetSum() < 10000)) {
            System.out.println("**This request " + request.GetID()
                    + " will be handled by " + this.Name + " **");
        } else {
            successor.ProcessRequest(request);
        }
    }
}

副总

public class VicePresidentApprover extends Approver {
    public VicePresidentApprover(String Name) {
        super(Name + " Vice President");
    }
    @Override
    public void ProcessRequest(PurchaseRequest request) {
        if ((10000 <= request.GetSum()) && (request.GetSum() < 50000)) {
            System.out.println("**This request " + request.GetID()
                    + " will be handled by " + this.Name + " **");
        } else {
            successor.ProcessRequest(request);
        }
    }
}

总裁:

public class PresidentApprover extends Approver {
    public PresidentApprover(String Name) {
        super(Name + " President");
    }
    @Override
    public void ProcessRequest(PurchaseRequest request) {
        if (50000 <= request.GetSum()) {
            System.out.println("**This request " + request.GetID()
                    + " will be handled by " + this.Name + " **");
        }else {
            successor.ProcessRequest(request);
        }
    }
}

待处理的请求:

public class PurchaseRequest {
    private int Type = 0;
    private int Number = 0;
    private float Price = 0;
    private int ID = 0;
    public PurchaseRequest(int Type, int Number, float Price) {
        this.Type = Type;
        this.Number = Number;
        this.Price = Price;
    }
    public int GetType() {
        return Type;
    }
    public float GetSum() {
        return Number * Price;
    }
    public int GetID() {
        return (int) (Math.random() * 1000);
    }
}

客户端发送请求:

public class Client {
    public Client() {}
    public PurchaseRequest sendRequst(int Type, int Number, float Price) {
        return new PurchaseRequest(Type, Number, Price);
    }
}

测试:

public class MainTest {
    public static void main(String[] args) {    
        Client mClient=new Client();
        Approver GroupLeader=new GroupApprover("Tom");
        Approver DepartmentLeader=new DepartmentApprover("Jerry");
        Approver VicePresident=new VicePresidentApprover("Kate");
        Approver President=new PresidentApprover("Bush");
        
        GroupLeader.SetSuccessor(VicePresident);
        DepartmentLeader.SetSuccessor(President);
        VicePresident.SetSuccessor(DepartmentLeader);
        President.SetSuccessor(GroupLeader);
        
        VicePresident.ProcessRequest(mClient.sendRequst(1, 100, 40));
        VicePresident.ProcessRequest(mClient.sendRequst(2, 200, 40));
        VicePresident.ProcessRequest(mClient.sendRequst(3, 300, 40));
        VicePresident.ProcessRequest(mClient.sendRequst(4, 400, 140));
    }
}

执行结果:

**This request 712 will be handled by Tom GroupLeader **
**This request 589 will be handled by Jerry DepartmentLeader **
**This request 667 will be handled by Kate Vice President **
**This request 855 will be handled by Bush President **
  • 优点:

    • 1.将请求的发送者与接收者解耦,使多个对象都有机会处理。
    • 2.简化处理器对象的结构,无需知道链的关系。
    • 3.可以动态的增删处理请求链结构。也可以指定从任意处理器开始处理。
  • 对比状态模式、策略模式:
    从UML类图看,这三种模式很是相近,容易使人混淆。前面的状态模式中已经对比了状态模式与策略模式,这里对比下状态与责任链模式:
    状态模式:是让各个状态对象自己知道其下一个处理的对象是谁,即在编译时便设定。设计思路是把逻辑判断转移到各个State类的内部,执行时客户端通过调用环境—Context类的方法来间接执行状态类的行为,客户端不直接和状态交互。
    职责链模式:各个对象并不指定其下一个处理的对象到底是谁,而是在客户端设定某个类型的链条,请求发出后穿越链条,直到被某个职责类处理或者链条结束。设计思路是把各个业务逻辑判断封装到不同职责类,且携带下一个职责的对应引用,但不像状态模式那样需要明确知道这个引用指向谁,而是在环境类设置链接方式或者过程。使用时,向链的第一个子类的执行方法传递参数就可以。客户端去通过环境类调用责任链,全自动运转起来。

相关文章

网友评论

      本文标题:责任链模式

      本文链接:https://www.haomeiwen.com/subject/mrqnaxtx.html