java设计模式——职责链模式

学校 OA系统的采购审批项目

需求是采购一批教材

  1. 如果金额小于等于 5000,由教学主任审批(0<=x<=5000)。
  2. 如果金额小于等于 10000,由院长审批 (5000
  3. 如果金额小于等于 30000,由副校长审批 (10000
  4. 如果金额超过 30000以上,有校长审批 ( 30000

传统方案解决 OA系统审批,传统的设计方案(类图)

java设计模式——职责链模式_第1张图片

问题分析

  1. 传统方式是:接收到一个采购请求后,根据采购金额来调用对应的 Approver (审批人)完成审批。
  2. 传统方式的问题分析 :客户端这里会使用到分支判断(比如 switch)来对不同的采购请求处理,这样就存在如下问题 :
  • 如果各个级别的人员审批金额发生变化,在客户端的也需要变化
  • 客户端必须明确的知道有多少个审批级别和访问
  1. 这样对一个采购请求进行处理和 Approver (审批人)就存在强耦合关系,不利于代码的扩展和维护。
  1. 解决方案:职责链模式

职责链模式基本介绍

  1. 职责链模式(Chain of Responsibility Pattern),又叫责任链模式,为请求创建了一个接收者对象的链(简单示意图)。这种模式对请求的发送者和接收者进行解耦。
  2. 职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
  3. 这种类型的设计模式属于行为型模式。

职责链模式的原理类图

java设计模式——职责链模式_第2张图片

  1. Handler :抽象的处理者,定义了一个处理请求的接口,同时含义另外 Handler。
  2. ConcreteHandlerA , B是具体的处理者,处理它自己负责的请求,可以访问它的后继者(即下一个处理者),如果可以处理当前请求,则处理,否则就将该请求交个后继者去处理,从而形成一个职责链。
  3. Request ,含义很多属性,表示一个请求。

OA系统采购审批

java设计模式——职责链模式_第3张图片
代码实现:

package com.jinxu.responsibilitychain;

public abstract class Approver {

	Approver approver;  //下一个处理者
	String name; // 名字
	
	public Approver(String name) {
		// TODO Auto-generated constructor stub
		this.name = name;
	}

	//下一个处理者
	public void setApprover(Approver approver) {
		this.approver = approver;
	}
	
	//处理审批请求的方法,得到一个请求, 处理是子类完成,因此该方法做成抽象
	public abstract void processRequest(PurchaseRequest purchaseRequest);
	
}

package com.jinxu.responsibilitychain;

public class Client {

	public static void main(String[] args) {

		//创建一个请求
		PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1);
		
		//创建相关的审批人
		DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
		CollegeApprover collegeApprover = new CollegeApprover("李院长");
		ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
		SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");
	
	
		//需要将各个审批级别的下一个设置好 (处理人构成环形: )
		departmentApprover.setApprover(collegeApprover);
		collegeApprover.setApprover(viceSchoolMasterApprover);
		viceSchoolMasterApprover.setApprover(schoolMasterApprover);
		schoolMasterApprover.setApprover(departmentApprover);
		
		
		
		departmentApprover.processRequest(purchaseRequest);
		viceSchoolMasterApprover.processRequest(purchaseRequest);
	}

}

package com.jinxu.responsibilitychain;

public class CollegeApprover extends Approver {

	public CollegeApprover(String name) {
		// TODO Auto-generated constructor stub
		super(name);
	}
	
	@Override
	public void processRequest(PurchaseRequest purchaseRequest) {

		if(purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {
			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
		}else {
			approver.processRequest(purchaseRequest);
		}
	}
}

package com.jinxu.responsibilitychain;

public class DepartmentApprover extends Approver {

	
	public DepartmentApprover(String name) {
		// TODO Auto-generated constructor stub
		super(name);
	}
	
	@Override
	public void processRequest(PurchaseRequest purchaseRequest) {

		if(purchaseRequest.getPrice() <= 5000) {
			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
		}else {
			approver.processRequest(purchaseRequest);
		}
	}

}

package com.jinxu.responsibilitychain;


//请求类
public class PurchaseRequest {

	private int type = 0; //请求类型
	private float price = 0.0f; //请求金额
	private int id = 0;
	//构造器
	public PurchaseRequest(int type, float price, int id) {
		this.type = type;
		this.price = price;
		this.id = id;
	}
	public int getType() {
		return type;
	}
	public float getPrice() {
		return price;
	}
	public int getId() {
		return id;
	}
	
	
	
	
	
}

package com.jinxu.responsibilitychain;

public class SchoolMasterApprover extends Approver {

	public SchoolMasterApprover(String name) {
		// TODO Auto-generated constructor stub
		super(name);
	}
	
	@Override
	public void processRequest(PurchaseRequest purchaseRequest) {

		if(purchaseRequest.getPrice() > 30000) {
			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
		}else {
			approver.processRequest(purchaseRequest);
		}
	}
}

package com.jinxu.responsibilitychain;

public class ViceSchoolMasterApprover extends Approver {

	public ViceSchoolMasterApprover(String name) {
		// TODO Auto-generated constructor stub
		super(name);
	}
	
	@Override
	public void processRequest(PurchaseRequest purchaseRequest) {

		if(purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
		}else {
			approver.processRequest(purchaseRequest);
		}
	}
}

职责链模式的注意事项和细节

  1. 将请求和处理分开,实现解耦,提高系统的灵活性。
  2. 简化了对象,使对象不需要知道链的结构。
  3. 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在 setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能。
  4. 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
  5. 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web中 Tomcat对 Encoding的处理、拦截器等。

java设计模式往期回顾:

  • 设计模式原则demo示例下载
  1. java设计模式
  2. java设计模式原则——单一职责原则
  3. java设计模式原则——接口隔离原则
  4. java设计模式原则——依赖倒置原则
  5. java设计模式原则——里氏替换原则
  6. java设计模式原则——开闭原则
  7. java设计模式原则——迪米特法则
  8. java设计模式原则——合成复用原则
  9. java设计模式概述和分类
  10. java设计模式——单例模式
  11. java设计模式——工厂模式
  12. java设计模式——原型模式
  13. java设计模式——建造者模式
  14. java设计模式——适配器模式
  15. java设计模式——桥接模式
  16. java设计模式——装饰者模式
  17. java设计模式——组合模式
  18. java设计模式——外观模式
  19. java设计模式——享元模式
  20. java设计模式——代理模式
  21. java设计模式——模板方法模式
  22. java设计模式——命令模式
  23. java设计模式——访问者模式
  24. java设计模式——迭代器模式
  25. java设计模式——观察者模式
  26. java设计模式——中介者模式
  27. java设计模式——备忘录模式
  28. java设计模式——解释器模式
  29. java设计模式——状态模式
  30. java设计模式——策略模式

你可能感兴趣的:(java设计模式)