`

设计模式(22)- 职责者模式

阅读更多

职责者模式

1.定义

      使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2.示例代码

      以公司聚餐的餐费申请和差旅费申请为例,说明职责者模式通用框架。

 

/* 通用的请求对象*/
public class RequestModel {
    /* 表示具体的业务类型*/
    private String type;
    /*通过构造方法把具体的业务类型传递进来*/
    public RequestModel(String type){
       this.type = type;
    }
    public String getType() {
       return type;
    }  
}

/* 定义职责对象的接口*/
public abstract class Handler {
    /* 持有下一个处理请求的对象*/
    protected Handler successor = null;
    /*设置下一个处理请求的对象*/
    public void setSuccessor(Handler successor){
       this.successor = successor;
    }
    /*通用的请求处理方法*/
    public Object handleRequest(RequestModel rm){
       if(successor != null){
           //这个是默认的实现,如果子类不愿意处理这个请求,
           //那就传递到下一个职责对象去处理
           return this.successor.handleRequest(rm);
       }else{
           System.out.println("没有后续处理或者暂时不支持这样的功能处理");
           return false;
       }
    }
}

   

/*封装跟聚餐费用申请业务相关的请求数据*/
public class FeeRequestModel extends RequestModel{
    /* 约定具体的业务类型 */
    public final static String FEE_TYPE = "fee";
    public FeeRequestModel() {
       super(FEE_TYPE);
    }
    /*申请人*/
    private String user;
    /*申请金额*/
    private double fee;
    public String getUser() {
       return user;
    }
    public void setUser(String user) {
       this.user = user;
    }
    public double getFee() {
       return fee;
    }
    public void setFee(double fee) {
       this.fee = fee;
    }
}

/*实现项目经理处理聚餐费用申请的对象*/
public class ProjectManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的项目经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //项目经理的权限比较小,只能在500以内
       if(frm.getFee() < 500){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "项目经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "项目经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //超过500,继续传递给级别更高的人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*实现部门经理处理聚餐费用申请的对象*/
public class DeptManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的部门经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //部门经理的权限比较小,只能在1000以内
       if(frm.getFee() < 1000){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "部门经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "部门经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //超过1000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*实现总经理处理聚餐费用申请的对象*/
public class GeneralManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的总经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //总经理1000以上
       if(frm.getFee() > 1000){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "总经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "总经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //后续人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*客户端调用申请聚餐费用*/
public class Client {
    public static void main(String[] args) {
       //先要组装职责链   
       Handler h1 = new GeneralManager();
       Handler h2 = new DepManager();
       Handler h3 = new ProjectManager();
       h3.setSuccessor(h2);
       h2.setSuccessor(h1);
       //开始测试申请聚餐费用
       FeeRequestModel frm = new FeeRequestModel();
       frm.setFee(300);
       frm.setUser("小李");
       //调用处理
       String ret1 = (String)h3.handleRequest(frm);
       System.out.println("ret1="+ret1);      
       //重新设置申请金额,再调用处理
       frm.setFee(800);    
       h3.handleRequest(frm);
       String ret2 = (String)h3.handleRequest(frm);
       System.out.println("ret2="+ret2);      
       //重新设置申请金额,再调用处理
       frm.setFee(1600);   
       h3.handleRequest(frm);
       String ret3 = (String)h3.handleRequest(frm);
       System.out.println("ret3="+ret3);
    }
}

  

/* 封装跟预支差旅费申请业务相关的请求数据*/
public class PreFeeRequestModel extends RequestModel{
    /* 约定具体的业务类型*/
    public final static String FEE_TYPE = "preFee";
    public PreFeeRequestModel() {
       super(FEE_TYPE);
    }
    /* 申请人*/
    private String user;
    /* 申请金额 */
    private double fee;
    public String getUser() {
       return user;
    }
    public void setUser(String user) {
       this.user = user;
    }
    public double getFee() {
       return fee;
    }
    public void setFee(double fee) {
       this.fee = fee;
    }
}

/**
 * 实现为项目经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的项目经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class ProjectManager2 extends ProjectManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //项目经理的权限比较小,只能在5000以内
       if(frm.getFee() < 5000){
           //工作需要嘛,统统同意
           System.out.println("项目经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //超过5000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/**
 * 实现为部门经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的部门经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class DeptManager2 extends DeptManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //部门经理的权限比较小,只能在10000以内
       if(frm.getFee() < 10000){
           //工作需要嘛,统统同意
           System.out.println("部门经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //超过10000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/**
 * 实现为总经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的总经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class GeneralManager2 extends GeneralManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //总经理10000以上
       if(frm.getFee() > 10000){
           //工作需要嘛,统统同意
           System.out.println("总经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //后续人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/*经理们既可以审批餐费,又可以审批差旅费,客户端调用*/
public class Client {
    public static void main(String[] args) {
       //先要组装职责链   
       Handler h1 = new GeneralManager2();
       Handler h2 = new DepManager2();
       Handler h3 = new ProjectManager2();
       h3.setSuccessor(h2);
       h2.setSuccessor(h1);      
       //开始测试申请聚餐费用
       FeeRequestModel frm = new FeeRequestModel();
       frm.setFee(300);
       frm.setUser("小李");
       //调用处理
       String ret1 = (String)h3.handleRequest(frm);
       System.out.println("ret1="+ret1);   
       //重新设置申请金额,再调用处理
       frm.setFee(800);    
       h3.handleRequest(frm);
       String ret2 = (String)h3.handleRequest(frm);
       System.out.println("ret2="+ret2);   
       //重新设置申请金额,再调用处理
       frm.setFee(1600);   
       h3.handleRequest(frm);
       String ret3 = (String)h3.handleRequest(frm);
       System.out.println("ret3="+ret3);      
       //开始测试申请预支差旅费用
       PreFeeRequestModel pfrm = new PreFeeRequestModel();
       pfrm.setFee(3000);
       pfrm.setUser("小张");
       //调用处理
       h3.handleRequest(pfrm);
       //重新设置申请金额,再调用处理
       pfrm.setFee(6000);
       h3.handleRequest(pfrm);
       //重新设置申请金额,再调用处理
       pfrm.setFee(36000);
       h3.handleRequest(pfrm);
    }
}

 

 3.实际应用

     在实际开发中,经常会出现一个把职责链稍稍变形的用法。在标准的职责链中,一个请求在职责链中传递,只要有一个对象处理了这个请求,就会停止。现在稍稍变一下,改成一个请求在职责链中传递,每个职责对象负责处理请求的某一方面的功能,处理完成后,不是停止,而是继续向下传递请求,当请求通过很多职责对象处理过后,功能也就处理完了,把这样的职责链称为功能链。

职责者模式的本质:分离职责,动态组合。

 

 

分享到:
评论

相关推荐

    设计模式-职责链模式(讲解及其实现代码)

    设计模式-职责链模式(讲解及其实现代码)

    设计模式 - 职责链模式(C++实例)

    职责链模式 设计模式 Chain of Responsibility 若有问题望指出。

    设计模式--C++

    1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...

    C# 设计模式-建造者模式

    设计模式-建造者模式,该模式涉及产品,构造者,指挥者、调用者等几个角色,职责明确,在实际项目中使用得比较多。

    设计模式:职责链模式

    设计模式之职责链模式的代码详解,简单明了的将模式思想以代码编写出来,常用的设计模式

    设计模式--可复用面向对象软件的基础

    1.2 Smalltalk MVC中的设计模式 1.3 描述设计模式 1.4 设计模式的编目 1.5 组织编目 1.6 设计模式怎样解决设计问题 1.7 怎样选择设计模式 1.8 怎样使用设计模式 第二章 实例研究:设计一个文档编辑器 2.1 设计问题...

    Java设计模式-装饰者模式

    本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧...——《Head First 设计模式》

    java 23种设计模式.zip

    设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...

    【资源免费下载】Java代码积累丨大话设计模式(Java实现版本)、线程协作

    Java代码积累:并发 设计模式 数据结构 使用容器 实用 类 基础知识 并发性 演示线程的生命周期 生产者-消费者 设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者...

    《C++20设计模式》学习笔记-第13章职责链模式-配套代码

    《C++20设计模式》学习笔记-第13章职责链模式-配套代码

    职责链模式--python

    参考&lt;大话设计模式&gt;,采用python书写的模板类。职责链模式。

    c++设计模式-结构型模式-装饰器模式

    c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    JAVA设计模式chm文档

    创建模式: ...设计模式之Chain of Responsibility(职责链) 设计模式之Command 设计模式之State 设计模式之Strategy(策略) 设计模式之Mediator(中介者) 设计模式之Interpreter(解释器) 设计模式之Visitor

    C#23种设计模式样例代码和UML图

    C#23种设计模式样例代码和UML图等 创建型模式(抽象工厂模式、工厂方法模式、单例模式、建造者模式、原型模式); 行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 ...

    Java 23种设计模式17职责链模式.pdf

    Java 23种设计模式17职责链模式.pdf

    C#设计模式.PDF

    设计模式(22)-Strategy Pattern 211 一、 策略(Strategy)模式 211 二、 策略模式的结构 212 三、 示意性源代码 212 四、 何时使用何种具体策略角色 215 五、 一个实际应用策略模式的例子 215 六、 在什么情况下...

    设计模式:可复用面向对象软件的基础--详细书签版

    整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法可以作为后来者的榜样。如果要知道怎样恰当定义和描述设计模式,我们应该可以从他们那儿获得启发”--steve...

    23种设计模式经典案例(C++版)

    设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计...

    尚硅谷设计模式源码笔记课件.zip

    设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂...

    研磨设计模式-part2

    《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...

Global site tag (gtag.js) - Google Analytics