bylijinnan 发表于 2013-2-3 13:26:01

读《研磨设计模式》-代码笔记-职责链模式-Chain Of Responsibility

声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/



/** * 业务逻辑:项目经理只能处理500以下的费用申请,部门经理是1000,总经理不设限。简单起见,只同意“Tom”的申请 * bylijinnan */abstract class Handler {/* 持有一个同类型的引用。有点像链表。网上也有职责链和链表的分析 * 目前我理解两者的不同是: * 1.职责链是变动的,组建职责链时可动态组合 * 2.链表只有一个入口,但职责链可从中间某点开始,跳过一些点 */protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}//可根据实际情况是否传递参数public abstract String handleRequest(String user, double fee);}//项目经理class ProjectManager extends Handler {public String handleRequest(String user, double fee) {String result = "";if (fee < 500) {if ("Tom".equals(user)) {result = "ProjectManager approved. User = " + user + ", fee = " + fee;} else {result = "ProjectManager rejected. User = " + user + ", fee = " + fee;}} else {if (this.successor != null) {result = this.successor.handleRequest(user, fee);}}return result;}}//部门经理class DivisionManager extends Handler {public String handleRequest(String user, double fee) {String result = "";if (fee < 1000) {if ("Tom".equals(user)) {result = "DivisionManager approved. User = " + user + ", fee = " + fee;} else {result = "DivisionManager rejected. User = " + user + ", fee = " + fee;}} else {if (this.successor != null) {result = this.successor.handleRequest(user, fee);}}return result;}}//总经理class GeneralManager extends Handler {public String handleRequest(String user, double fee) {String result = "";if ("Tom".equals(user)) {result = "GeneralManager approved. User = " + user + ", fee = " + fee;} else {result = "GeneralManager rejected. User = " + user + ", fee = " + fee;}/*//我们定义总经理是这个流程的最后一环,因此就不再传递了if (this.successor != null) {result = this.successor.handleRequest(user, fee);}*/return result;}}/** * 扩展一:如果要新增另一个费用的审批流程呢? * 当然可以这样写,在Handler里面新增一个处理流程的方法: *public abstract String handleAnotherRequest(String user, double whateverFee); * 书上介绍了另一个更易于扩展的方法,如下 */abstract class Handlerr {protected Handlerr successor;public void setSuccessor(Handlerr successor) {this.successor = successor;}/** * 子类应该重写本方法来实现具体的业务逻辑 * @param requestModel 申请业务数据类型 包括申请人、申请金额、费用类型 * @return处理结果。为兼容不同的返回类型(String or boolean),返回类型设为Object--我觉得这样不好,容易造成混乱 */public Object handleRequest(RequestModel requestModel) {Object result = null;if (successor != null) {result = this.successor.handleRequest(requestModel);} else {System.out.println("没有后续处理或者暂时不支持后续处理");}return result;}}//项目经理1.处理OneRequestModel的申请class ProjectManagerr extends Handlerr {public Object handleRequest(RequestModel requestModel) {Object result = null;//假设只处理类型为OneRequestModel的申请if (requestModel.getRequestType() == OneRequestModel.TYPE_ONE) {result = this.handleTypeOneRequest(requestModel);} else {result = super.handleRequest(requestModel);}return result;}private Object handleTypeOneRequest(RequestModel requestModel) {String result = null;//这里面的业务逻辑跟之前的ProjectManager是一样的if (requestModel.getFee() < 500) {if ("Tom".equals(requestModel.getUser())) {result = "ProjectManager approved. RequestModel = " + requestModel;} else {result = "ProjectManager rejected. RequestModel = " + requestModel;}} else {if (this.successor != null) {return this.successor.handleRequest(requestModel);}}return result;}}//项目经理2.处理AnotherRequestModel的申请class ProjectManagerr2 extends ProjectManagerr {public Object handleRequest(RequestModel requestModel) {Object result = false;//假设只处理类型为AnotherRequestModel的申请if (requestModel.getRequestType() == AnotherRequestModel.TYPE_ANOTHER) {result = this.handleTypeAnotherRequest(requestModel);} else {result = super.handleRequest(requestModel);}return result;}private Object handleTypeAnotherRequest(RequestModel requestModel) {boolean result = false;//这里面的业务逻辑跟之前的ProjectManager是一样的if (requestModel.getFee() < 500) {if ("Tom".equals(requestModel.getUser())) {result = true;System.out.println("ProjectManager2 approved. RequestModel = " + requestModel);} else {result = false;System.out.println("ProjectManager2 rejected. RequestModel = " + requestModel);}} else {if (this.successor != null) {return this.successor.handleRequest(requestModel);}}return result;}}class RequestModel {private String user;//申请人private double fee;//费用private int requestType;//费用类型public RequestModel(String user, double fee, int requestType) {this.user = user;this.fee = fee;this.requestType = requestType;}public String getUser() {return user;}public double getFee() {return fee;}public int getRequestType() {return requestType;}public void setUser(String user) {this.user = user;}public void setFee(double fee) {this.fee = fee;}public void setRequestType(int requestType) {this.requestType = requestType;}public String toString() {return "user = " + this.user + ",fee = " + this.fee + ",requestType = " + this.requestType;}}class OneRequestModel extends RequestModel {public static int TYPE_ONE= 1;public OneRequestModel(String user, double fee, int requestType) {super(user, fee, TYPE_ONE);}}class AnotherRequestModel extends RequestModel {public static int TYPE_ANOTHER= 2;public AnotherRequestModel(String user, double fee, int requestType) {super(user, fee, TYPE_ANOTHER);}}/** * 扩展二:功能链。比较典型的应用是Java Web开发里面的filter * 业务逻辑:保存销售信息。保存之前要进行权限检查和数据检查 */class GoodsSaleBO {/** * 保存商品销售信息 * @param user销售人员 * @param customer客户 * @param saleModel * @return true-保存成功 false-保存失败 */public boolean save(String user, String customer, SaleModel saleModel) {//构建功能链PrivilegeCheckSaleHandler privilegeCheckSaleHandler = new PrivilegeCheckSaleHandler();DataCheckSaleHandler dataCheckSaleHandler = new DataCheckSaleHandler();DataSaveSaleHandler dataSaveSaleHandler = new DataSaveSaleHandler();privilegeCheckSaleHandler.setSuccessor(dataCheckSaleHandler);dataCheckSaleHandler.setSuccessor(dataSaveSaleHandler);return privilegeCheckSaleHandler.save(user, customer, saleModel);}}abstract class SaleHandler {protected SaleHandler successor;public void setSuccessor(SaleHandler successor) {this.successor = successor;}public abstract boolean save(String user, String customer, SaleModel saleModel);}//权限检查class PrivilegeCheckSaleHandlerextends SaleHandler {public boolean save(String user, String customer, SaleModel saleModel) {if ("Tom".equals(user)) {return this.successor.save(user, customer, saleModel);} else {System.out.println("对不起," + user + ",您没有保存销售信息的权限");return false;}}}//数据检查class DataCheckSaleHandler extends SaleHandler {public boolean save(String user, String customer, SaleModel saleModel) {if (emptyStr(user)) {System.out.println("操作人不能为空");return false;}if (emptyStr(customer)) {System.out.println("客户不能为空");return false;}if (saleModel == null || emptyStr(saleModel.getGoods()) || 0 == saleModel.getSoldNum()) {System.out.println("SaleModel数据有误");return false;}return this.successor.save(user, customer, saleModel);}private boolean emptyStr(String str) {return str == null || str.trim().length() == 0;}}//真正保存的操作class DataSaveSaleHandler extends SaleHandler {public boolean save(String user, String customer, SaleModel saleModel) {System.out.println(user + "保存了如下信息:客户--" + customer + ",销售数据-- " + saleModel);return true;}}class SaleModel {private String goods;//商品名称private int soldNum;//销售数量public String getGoods() {return goods;}public void setGoods(String goods) {this.goods = goods;}public int getSoldNum() {return soldNum;}public void setSoldNum(int soldNum) {this.soldNum = soldNum;}public String toString() {return "goods = " + this.goods + ",soldNum = " + this.soldNum;}}/** * 这个类是用来测试的 */public class ChainOfResponsibilityPattern {public static void main(String[] args) {//测试费用(一种费用)申请ProjectManager projectManager = new ProjectManager();DivisionManager divisionManager = new DivisionManager();GeneralManager generalManager = new GeneralManager();projectManager.setSuccessor(divisionManager);divisionManager.setSuccessor(generalManager);System.out.println(projectManager.handleRequest("Tom", 499));System.out.println(projectManager.handleRequest("Tom", 999));System.out.println(projectManager.handleRequest("Tom", 1999));System.out.println(projectManager.handleRequest("James", 499));System.out.println(projectManager.handleRequest("James", 999));System.out.println(projectManager.handleRequest("James", 1999));//测试“功能链”:保存销售信息SaleModel saleModel = new SaleModel();saleModel.setGoods("iphone5");saleModel.setSoldNum(10);GoodsSaleBO goodsSaleBO = new GoodsSaleBO();goodsSaleBO.save("Tom", "Mr.Lee", saleModel);goodsSaleBO.save("Jack", "Mr.Lee", saleModel);}}
页: [1]
查看完整版本: 读《研磨设计模式》-代码笔记-职责链模式-Chain Of Responsibility