一、责任链模式
如果有多个对象都有机会处理请求,责任链可使请求的发送者和接收者解耦,请求沿着责任链传递,直到有一个对象处理了它为止。
二、示例
公司采购安排的项目:公司内部要采购物品的话,不同的价格则需要不同阶层的领导签字,决策人有组长、部长、副总、总裁
使用传统的方法可是用switch语句将不同的价格区分不同的决策人,但是这样所有的逻辑都在一个处理类中较复杂,且如果中间增加或减少了决策人拓展不便
为了实现对象之间更好的解耦,则引入责任链模式,将请求从低到高一层一层的往下传,如果本人执行不了,就传递给下一层执行,直到有对象可以处理为止
1.定义采购对象
/**
* 采购对象,主要是价格
*/
public class PurchaseRequest {
private int Type = 0;
private int Number = 0;
private float Price = 0;
private int ID = 0;
public PurchaseRequest(int Type, int Number, float Price) {
this.Type = Type;
this.Number = Number;
this.Price = Price;
}
public int GetType() {
return Type;
}
public float GetSum() {
return Number * Price;
}
public int GetID() {
return (int) (Math.random() * 1000);
}
}
2.定义决策者的抽象类
/**
* 责任链模式,管理者抽象对象,定义自己的处理内容和设置下一个责任链对象
*/
public abstract class Approver {
Approver successor;
String Name;
public Approver(String Name) {
this.Name = Name;
}
public abstract void ProcessRequest(PurchaseRequest request);
public void SetSuccessor(Approver successor) {
this.successor = successor;
}
}
3.各决策者在自己的责任范围内实现责任方法
/**
* 责任链模式,组长的责任,不在权限范围内就往下传
*/
public class GroupApprover extends Approver {
public GroupApprover(String Name) {
super(Name + " GroupLeader");
}
@Override
public void ProcessRequest(PurchaseRequest request) {
if (request.GetSum() < 5000) {
System.out.println("**This request " + request.GetID()
+ " will be handled by "
+ this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
/**
* 责任链模式,部门经理的责任,不在权限范围内就往下传
*/
public class DepartmentApprover extends Approver {
public DepartmentApprover(String Name) {
super(Name + " DepartmentLeader");
}
@Override
public void ProcessRequest(PurchaseRequest request) {
if ((5000 <= request.GetSum()) && (request.GetSum() < 10000)) {
System.out.println("**This request " + request.GetID()
+ " will be handled by " + this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
/**
* 责任链模式,副经理的责任,不在权限范围内就往下传
*/
public class VicePresidentApprover extends Approver {
public VicePresidentApprover(String Name) {
super(Name + " Vice President");
}
@Override
public void ProcessRequest(PurchaseRequest request) {
if ((10000 <= request.GetSum()) && (request.GetSum() < 50000)) {
System.out.println("**This request " + request.GetID()
+ " will be handled by " + this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
/**
* 责任链模式,总经理的责任,不在权限范围内就往下传
*/
public class PresidentApprover extends Approver {
public PresidentApprover(String Name) {
super(Name + " President");
}
@Override
public void ProcessRequest(PurchaseRequest request) {
if (50000 <= request.GetSum()) {
System.out.println("**This request " + request.GetID()
+ " will be handled by " + this.Name + " **");
} else {
successor.ProcessRequest(request);
}
}
}
4.定义每一层决策者的下一层决策对象,调用时直接调用最上层即可
/**
* 责任链模式,将任务的处理封装层一个个对象,实现处理之间解耦,一层一层的往下传
*/
public class MainTest {
public static void main(String[] args) {
Client mClient=new Client();
Approver GroupLeader=new GroupApprover("Tom");
Approver DepartmentLeader=new DepartmentApprover("Jerry");
Approver VicePresident=new VicePresidentApprover("Kate");
Approver President=new PresidentApprover("Bush");
GroupLeader.SetSuccessor(VicePresident);
DepartmentLeader.SetSuccessor(President);
VicePresident.SetSuccessor(DepartmentLeader);
President.SetSuccessor(GroupLeader);
VicePresident.ProcessRequest(mClient.sendRequst(1, 100, 40));
VicePresident.ProcessRequest(mClient.sendRequst(2, 200, 40));
VicePresident.ProcessRequest(mClient.sendRequst(3, 300, 40));
VicePresident.ProcessRequest(mClient.sendRequst(4, 400, 140));
}
}
三、总结
- 优点:
- 将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求
- 可以简化对象,因为它无须知道链的结构
- 可以动态地增加或删减处理请求的链结构
- 缺点:
- 请求从链的开头进行遍历,对性能有一定的损耗
- 并不保证请求一定被处理
- 适用场合:
- 有多个对象可以处理一个请求
- 不明确接收者的情况
- 责任链可有序、无序链,线型、树形、环形链
Java设计模式所有示例代码,持续更新中