`

读《研磨设计模式》-代码笔记-职责链模式-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 PrivilegeCheckSaleHandler  extends 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);
		
	}

}

4
4
分享到:
评论
1 楼 weareyou-006 2012-09-17  
不错!

相关推荐

    研磨设计模式-配套源代码

    "研磨设计模式-配套源代码"很显然是一份与学习和理解设计模式相关的资源,其中包含了实际的编程示例。这份压缩包可能包括了多种常见设计模式的实现,如单例模式、工厂模式、观察者模式、装饰器模式等,通过源代码的...

    研磨设计模式-配套源代码.7z

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,其配套源代码包含了许多经典设计模式的实际应用示例。这些源代码可以帮助读者更直观地理解设计模式的原理和使用方法,进一步提升软件开发能力。 设计模式是软件...

    研磨设计模式-配套源代码.rar

    《研磨设计模式》是一本深入探讨软件设计模式的书籍,配套源代码是作者为了帮助读者更好地理解和应用书中介绍的设计模式而提供的实践示例。设计模式是软件开发中经过实践检验的、解决常见问题的模板,它为软件设计...

    研磨设计模式-配套源代码 UTF-8格式

    《研磨设计模式》是一本深入探讨软件设计原则与实践的经典书籍,其配套源代码提供了丰富的实例,帮助读者更好地理解和应用各种设计模式。这个UTF-8格式的压缩包包含了书中介绍的各种设计模式的实现,是学习和研究...

    设计模式Golang实现《研磨设计模式》读书笔记.zip

    设计模式Golang实现《研磨设计模式》读书笔记Go语言设计模式Go语言设计模式的实例代码创建模式工厂简单模式(Simple Factory)工厂方法模式(工厂方法)抽象工厂模式(Abstract Factory)创建者模式(Builder)原型...

    研磨设计模式-陈臣.epub

    “1.1 设计模式是什么 1.1.1 什么是模式 从字面上理解,模,就是模型、模板的意思;式,就是方式、方法的意思。综合起来,所谓模式就是:可以作为模型或模板的方式或方法。... “研磨设计模式”。 iBooks.

    研磨设计模式-陈臣.王斌.扫描高清版PDF

    设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;...

    研磨设计模式--chjavach的博客文章

    研磨设计模式的过程是持续学习和实践的过程,chjavach的博客文章提供了深入探讨这些模式的宝贵资源,值得我们仔细阅读和学习。通过深入理解和运用这些设计模式,可以提升个人的编程技巧,同时也为团队合作和项目维护...

    研磨设计模式-陈臣pdf

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

    研磨设计模式-part2

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF...第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式-part4

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF...第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式-part3

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF...第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式书-配套源代码(全)

    1:本源代码是《研磨设计模式》一书的配套源代码 2:每个模式的示例源代码放在一个单独的文件夹下,以该模式的英文名称命名 3:每个模式下分成多个example,按照书的示例顺序分别命名为example1、example2.........

    研磨设计模式-陈臣.mobi kindle版

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

    研磨设计模式源码

    《研磨设计模式源码》是一份非常宝贵的资源,它提供了设计模式的实践代码,帮助开发者深入理解并应用这些模式。设计模式是软件工程中经过长期实践总结出来的一套通用解决方案,它们描述了在特定场景下如何解决常见...

    研磨设计模式 源代码

    《研磨设计模式》是一本深入探讨软件设计模式的经典书籍,源代码包含了书中所讲解的各种设计模式的实际应用示例。设计模式是软件工程中的重要概念,它们是经过反复验证、在特定情境下解决常见问题的有效解决方案。...

    研磨设计模式(完整带书签).part2.pdf

    本电子书一共两个压缩文档,本文件为part2. ...第23章 职责链模式(Chain of Responsibility) 第24章 桥接模式(Bridge) 第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式全部源代码

    这个压缩包“研磨设计模式全部源代码”包含了多种设计模式的实现,这些模式可以帮助开发者写出更可维护、可扩展和可复用的代码。下面将详细讲解其中可能包含的一些重要设计模式及其应用。 1. 工厂模式:这是最简单...

    研磨设计模式PDF

    责任链模式(Chain of Responsibility)避免对象之间的耦合,使得多个对象有机会处理请求;解释器模式(Interpreter)定义语言的文法,并提供一个解释器来处理这种语言;迭代器模式(Iterator)提供了遍历聚合对象的...

    研磨设计模式带书签完整版228M.7z.001

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

Global site tag (gtag.js) - Google Analytics