设计模式之行为型模式(一)职责链模式

78 阅读4分钟

1.职责链模式 2.命令模式 3.迭代器模式 4.观察者模式 5.策略模式 6.模板方法模式 7.访问者模式 8.中介者模式 9.备忘录模式 10.状态模式

由于学习难度较大或相对用途较少 本章不会讲解7-10四种设计模式

接下来针对以上6种设计模式进行单独讲解

1 职责链模式

1.1 定义

避免将请求发送者与接收者耦合在一起,让多个对象都有机会接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

举例说明:采购系统中每个决策角色有自己可以审批的相应的额度,例如经理可以审批10万以下的额度,总监可以审批10-20万的额度,总裁可以审批20万以上的额度。

一般情况下对这种系统的设计如下:

 if(amount) < 100000 经理审批
 if(amount > 100000 && amount < 200000) 总监审批
 if(amount > 200000) 总裁审批

以上案例看起来可以实现需求,但是违反了单一职责原则,并且很难维护,当需要增加副总裁审批或者需要调整审批顺序删除总监审批步骤等时必须修改原有逻辑,违反开闭原则。

职责链模式就解决了这类问题,客户端只需将请求发送到服务端的链上,具体由哪个类执行该请求客户端不需要关心,请求可以在链上传递。由链上相应的处理者对请求进行处理。

1.2 UML图

image.png

从上面UML图中可以看出

Handler为抽象处理类,它定义了一个处理请求的接口,该类持有自身的对象,其目的时为了作为对下属链的引用。通过该引用,处理者可以连成一条链。

ConcreteHandler为具体处理类,它是抽象处理类的子类,可以处理用户请求。在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者。

1.3 代码实现

// 抽象处理类  
public abstract class Handler {  
    protected Handler next;  
  
    public Handler setNext(Handler handler) {  
        this.next = handler;  
        return this;  
    }  
  
    public abstract void handleRequest(String request);  
}  
  
// 具体处理类A  
public class ConcreteHandlerA extends Handler {  
    @Override  
    public void handleRequest(String request) {  
        // 仅当请求满足某个条件时才处理请求  
        if (request.startsWith("A")) {  
            // 处理请求A  
            System.out.println("ConcreteHandlerA handles: " + request);  
        } else {  
            // 否则将请求传递给下一个处理类  
            if (next != null) {  
                next.handleRequest(request);  
            }  
        }  
    }  
}  
  
// 具体处理类B  
public class ConcreteHandlerB extends Handler {  
    @Override  
    public void handleRequest(String request) {  
        // 处理请求B  
        System.out.println("ConcreteHandlerB handles: " + request);  
    }  
}  
  
// 客户端访问处理链的起点类  
public class Client {  
    public static void main(String[] args) {  
        ConcreteHandlerA handlerA = new ConcreteHandlerA();  
        ConcreteHandlerB handlerB = new ConcreteHandlerB();  
        handlerA.setNext(handlerB);  
        // 这将只由ConcreteHandlerA处理,因为请求以"A"开头。
        handlerA.handleRequest("A123");    
    }  
}

1.4 采购系统案例代码实现

// 抽象处理类  
public abstract class ApprovalHandler {  
    protected ApprovalHandler next;  
  
    public void setNext(ApprovalHandler handler) {  
        this.next = handler;  
    }  
  
    public abstract void handleApproval(double amount);  
}  
  
// 具体处理类经理审批  
public class ManagerApprovalHandler extends ApprovalHandler {  
    @Override  
    public void handleApproval(double amount) {  
        if (amount < 100000) {  
            System.out.println("经理审批通过,金额:" + amount);  
        } else if (next != null) {  
            next.handleApproval(amount);  
        } else {  
            System.out.println("金额不足100000,无需经理审批");  
        }  
    }  
}  
  
// 具体处理类总监审批  
public class DirectorApprovalHandler extends ApprovalHandler {  
    @Override  
    public void handleApproval(double amount) {  
        if (amount > 100000 && amount < 200000) {  
            System.out.println("总监审批通过,金额:" + amount);  
        } else if (next != null) {  
            next.handleApproval(amount);  
        } else {  
            System.out.println("金额不足200000,无需总监审批");  
        }  
    }  
}  
  
// 具体处理类总裁审批  
public class PresidentApprovalHandler extends ApprovalHandler {  
    @Override  
    public void handleApproval(double amount) {  
        if (amount > 200000) {  
            System.out.println("总裁审批通过,金额:" + amount);  
        } else if (next != null) {  
            next.handleApproval(amount);  
        } else {  
            System.out.println("金额不足,无需总裁审批");  
        }  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        // 假设需要审批的金额为150000 
        double amount = 150000;  
        ManagerApprovalHandler managerHandler = new ManagerApprovalHandler();  
        DirectorApprovalHandler directorHandler = new DirectorApprovalHandler();  
        PresidentApprovalHandler presidentHandler = new PresidentApprovalHandler();  
        managerHandler.setNext(directorHandler);  
        directorHandler.setNext(presidentHandler);  
        // 从经理开始审批,逐级传递到总裁结束  
        managerHandler.handleApproval(amount); 
    }  
}

1.5 拓展

职责链分为纯职责链和不纯职责链两种模式,所谓纯职责链模式便像上面代码一样,一个请求只能被链上的一个类处理。不允许链上有类处理完之后将该请求继续往下传递的情况,也不能出现有请求因为不满足任意条件而未被处理的情况。

不纯职责链模式则允许一个请求被链上多个类进行处理,并且可以不被任何类处理。