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

行为型模式(BehavioralPattern)是对在不同的对象之间划分责任和算法的抽象化。
行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。
通过行为型模式,可以更加清晰地划分类与对象的职责,并研究系统在运行时实例对象之间的交互。
在系统运行时,对象并不是孤立的,它们可以通过相互通信与协作完成某些复杂功能,
一个对象在运行时也将影响到其他对象的运行。

职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。由于英文翻译的不同,职责链模式又称为责任链模式,它是一种对象行为型模式。

模式结构

设计模式(三):行为型模式之职责链模式_第1张图片

实例练习:以设计职责链模式(Chain Of Responsibility)为实验实例,掌握“行为型模式”的工作原理、应用环境和应用方法。


练习内容
某企业的SCM(Supply Chain Management,供应链管理)系统中包含一个采购审批子系统。该企业的采购审批(PurchaseRequest)是分级进行的,即根据采购金额(money)的不同由不同层次的主管人员(Manager)来审批,主任(Director)可以审批5万元以下(不包括5万元)的采购单,副董事长(ViceChairman)可以审批5万元至10万元(不包括10万元)的采购单,董事长(Chairman)可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开董事会(BoardOfDirectors)讨论决定。如下图所示:
设计模式(三):行为型模式之职责链模式_第2张图片

使用职责链模式设计该程序,绘制类图并编程模拟实现。


练习过程
1.用UML设计“采购审批子系统”的类图;
使用 职责链模式设计了一个采购审批子系统的框架,通过创建职责链将所有处理者联系到一起,对采购审批进行分级处理。审批请求发出到职责链之后,请求沿着链传递,由链上的处理者对请求进行相应的处理。

基于职责链模式,首先创建一个抽象类Hander,具体的处理类型Director类、ViceChaiman类、Chairman类以及Board类都继承于它,并分别重写handleRequest()方法。接着创建PurchaseRequest类来描述审批单的具体属性,具体的结构关系见下类图。

设计模式(三):行为型模式之职责链模式_第3张图片

(图一:框架类图)

2.根据类图写出“采购审批子系统”的源代码;

绘制好PurchaseRequest类图之后,根据类图对程序框架代码进行编写。首先实现的是Hander抽象类,并在Hander类中声明好继承类将会用到的数据成员和所有方法,接着分别创建Director类、Chairman类、ViceChairman类和Board类,并根据实验要求,以不同的审批单金额分别重写handleRequest()方法。然后创建PurchaseRequest类,最后创建Client类,并根据实验要求实例化对象,通过调用setnextHander()函数实现各个对象间的关系。具体实现代码如下:

Board.java
public class Board extends Hander {
    public Board(String name) {
        super(name);
    }
    //@Override
    public voidhandleRequest(PurchaseRequest request) {
        if(request.getRequestMoney()>=50 ) {
             System.out.println(this.name + " -> 开会讨论");
        } else {
             if (getnextHander()!= null) {
                 System.out.println(this.name + " -> 不能处理,将交给 ->" + getnextHander().myName());
                 getnextHander().handleRequest(request);
             }
        }
    }
}


Chairman.java
public class Chairman extends Hander {
    public Chairman(String name) {
        super(name);
    }
    //@Override
    public voidhandleRequest(PurchaseRequest request) {
        if(request.getRequestMoney()< 50 && request.getRequestMoney() >=10) {
             System.out.println(this.name + " -> 同意");
        } else {
             if (getnextHander()!= null) {
                 System.out.println(this.name + " -> 不能处理,将交给 ->" + getnextHander().myName() );
                 getnextHander().handleRequest(request);
             }
        }
    }
}


 
Director.java
public class Chairman extends Hander {
    public Chairman(String name) {
        super(name);
    }
    //@Override
    public voidhandleRequest(PurchaseRequest request) {
        if(request.getRequestMoney()< 50 && request.getRequestMoney() >=10) {
             System.out.println(this.name + " -> 同意");
        } else {
             if (getnextHander()!= null) {
                 System.out.println(this.name + " -> 不能处理,将交给 ->" + getnextHander().myName() );
                 getnextHander().handleRequest(request);
             }
        }
    }
}


 
ViceChairman.java
public class ViceChairman extends Hander {
    publicViceChairman(String name) {
        super(name);
    }
    //@Override
    public voidhandleRequest(PurchaseRequest request) {
        if(request.getRequestMoney()< 10 && request.getRequestMoney() >=5 ) {
             System.out.println(this.name + " -> 同意");
        } else {
             if (getnextHander()!= null) {
                 System.out.println(this.name + " -> 不能处理,将交给 ->" + getnextHander().myName() );
                 getnextHander().handleRequest(request);
             }
        }
    }
}


Hander.java
public abstract class Hander {
    protected String name;
    protected Hander nextHander;  
 
    public Hander(String name) {  //节点名称
        this.name = name;
    }
    public String myName(){
        return  name;
    }
   
    public HandergetnextHander() {  //得到当前节点
        return nextHander;
    }
 
    public voidsetnextHander(Hander nextHander) {  //设置当前节点
        this.nextHander = nextHander;
    }
 
    public  abstract voidhandleRequest(PurchaseRequest request); //处理请求
}


PurchaseRequest.java
public class PurchaseRequest{
    private String RequestName;
    private int RequestMoney;
   
    publicPurchaseRequest(String RequestName, int RequestMoney) {
        this.RequestName = RequestName;
        this.RequestMoney = RequestMoney;
    }
   
    //get or set_________________
 
    public StringgetRequestName() {
        return RequestName;
    }
 
    public voidsetRequestname(String RequestName) {
        this.RequestName = RequestName;
    }
 
    public intgetRequestMoney() {
        return RequestMoney;
    }
 
    public void setRequestMoney(int RequestMoney) {
        this.RequestMoney = RequestMoney;
    
	}
}
 
  
Client.java
public class Client {
    public static void main(String[] args) {
       
        PurchaseRequest lr = new PurchaseRequest("小明", 50);
        Hander director =new Director("主   任");
        Hander vchairman =new ViceChairman("副董事长");
        Hander chairman =new Chairman("董 事 长");
        Hander board =new Board("董 事 会");
       
        director.setnextHander(vchairman);
        vchairman.setnextHander(chairman);
        chairman.setnextHander(board);
       
        director.handleRequest(lr);
    }
}

运行结果

设计模式(三):行为型模式之职责链模式_第4张图片

练习总结

本次练习基于职责链模式进行设计,内容是处理采购审批单,将各层级的处理者创建到一条职责链上,使得请求审批处理的人不需要了解具体改由谁来处理这个请求,只需将审批传递到职责链上。类似的,在生活中我们可以把一些具有特定业务范围的公司或机构看做一个整体,当我们有相应的业务需要处理的时候,只需要把这个请求发送到这个整体上,这个整个相当于职责链的头部,而公司或者机构内部的顺序处理者就是一个职责链。把这个业务工作交给具体的某个机构处理了之后,我们并不需要知道这个机构内部究竟是谁处理了这个事儿,只需要接收最后的处理结果就行。相比于组合模式,我觉得职责链模式的应用范围应该会更广一些。

职责链模式和递归询问非常相似,请求者只与链头部打交道。相比于迭代式的逐个和内部具体处理者打交道效率更高。由此降低耦合度,符合高类聚低耦合的原则,使得请求处理更为便捷。在现实生活中,这样的处理方式也乐于被人们接受。

对于课堂上提到的 职责链模式存在的不能保证请求一定被接收的缺点,即所有的对象都无法处理请求的情况下,我认为是不是所有的对象都无法处理请求是客观事实,与采用哪种模式无关。如果是缺点,那就是所有模式都没办法避免的缺点。




你可能感兴趣的:(设计模式)