声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客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);
}
}