`

设计模式(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.实际应用

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

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

 

 

分享到:
评论

相关推荐

    设计模式精解-GoF-23种设计模式解析--附C++源代码

    设计模式是软件工程中的一种最佳实践,用于解决在软件开发过程中常见的问题。这些模式是由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位大师,通常被称为GoF(Gang of Four),在他们的经典著作...

    C++设计模式--基于Qt4开源跨平台开发框架

    《C++设计模式--基于Qt4开源跨平台开发框架》一书主要探讨了如何在C++编程中利用设计模式,并结合Qt4框架进行高效的跨平台应用开发。设计模式是软件工程中的重要概念,它们是经过时间和实践验证的解决特定问题的模板...

    设计模式精解-GoF 23种设计模式解析附C++实现源码

    ### 设计模式精解——GoF 23种设计模式解析及C++实现源码 #### 引言 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。GoF(Gang of Four)所提出的23种设计模式,被认为是面向对象...

    设计模式精解-GoF 23种设计模式解析附C++.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现 #### 0. 引言 设计模式作为面向对象编程的核心组成部分,是软件开发者在长期实践中总结出来的最佳实践。通过深入理解这些设计模式,我们可以更好地进行面向...

    java设计模式---诙谐易懂版

    根据给定文件内容,以下是关于Java设计模式的知识点说明: 1. 策略模式(Strategy Pattern)是一种行为设计模式,允许在运行时选择算法的行为。策略模式的意图是定义一系列算法,将每个算法封装起来,并使它们可以...

    设计模式精解-GoF23种设计模式解析附C++实现源码

    设计模式是软件工程中的一种重要思想,它是在特定情境下,为解决常见问题而形成的一套最佳实践。GoF(Gang of Four)23种设计模式是软件开发中的经典,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides...

    设计模式精解-GoF 23种设计模式解析附C++实现源码.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现源码 #### 0. 引言 设计模式是软件工程领域的一个重要概念,它提供了一种解决常见问题的方法论。GoF(Gang of Four)所提出的23种设计模式被视为面向对象设计的...

    Java设计模式----通俗易懂版

    这个资源"Java设计模式----通俗易懂版"显然是一个专门针对初学者或需要深入理解设计模式的开发者编写的指南。作者以形象生动的例子解释了23种经典的Java设计模式,使得复杂的概念变得更加易于理解。 首先,我们要...

    设计模式精解-GoF 23种设计模式解析附C++实现源码 完整版

    《设计模式精解-GoF 23种设计模式解析附C++实现源码 完整版》是一份深入探讨软件工程中经典设计模式的重要资料,涵盖了面向对象编程中的核心设计原则和实践。这份资源主要关注GoF(Gang of Four,即《设计模式:可...

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

    职责链模式(Chain of Responsibility)是一种行为设计模式,它的核心思想是将一系列处理请求的对象组织成一条链,每个对象都包含对请求的处理或传递的责任。在C++中实现职责链模式,我们可以创建一个抽象处理器类,...

    新版设计模式手册 - C#设计模式(第二版)

    在C#设计模式(第二版)中,作者可能会深入讨论每种模式的动机、结构、参与者、协作方式以及优缺点。同时,书中还会通过实际的C#代码示例来演示如何在项目中应用这些模式,帮助读者理解模式背后的意图和使用场景。 ...

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码

    ### 设计模式精解—GoF 23种设计模式解析及C++实现源码 #### 0. 引言 设计模式作为一种重要的面向对象设计工具,在软件开发中扮演着至关重要的角色。本文旨在深入解析GoF(Gang of Four,四人组)提出的23种设计...

    26种设计模式-----pdf

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板。这个压缩包文件名为"26种设计模式",其中可能详细介绍了软件开发中的26个核心设计模式。这些模式是经过时间检验、被广泛接受并反复使用...

    设计模式---装饰者模式

    装饰者模式是一种结构型设计模式,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码或创建子类。这种模式的核心思想是通过将对象封装在一个装饰器对象内,来扩展对象的功能,同时保持原有接口的不变...

    设计模式PPT---25种设计模式详解

    这份PPT涵盖了设计模式的全貌,对于初学者来说,是一个很好的学习资源。通过深入学习这些模式,开发者可以更好地理解和应用面向对象设计原则,提升代码质量和可维护性。同时,理解并熟练运用设计模式,也是成为一名...

Global site tag (gtag.js) - Google Analytics