每一個公司對請假都是控制的很嚴格,必須要相關的人員簽字。三天,主任簽字;三到七天,經理簽字;一個星期副總經理簽字;以上總經理簽字。
模式定義
職責模式:使多個對象都有機會處理請求,進而避免請求的發送者與接收者之間的耦合關系。将這個對象連成一條鍊。并沿着這條鍊傳遞該請求,直到有一個對象處理為止。
在職責鍊模式中最關鍵的一點就是客戶送出請求後,請求沿着鍊往下傳遞直到有一個處理者處理它,在這裡客戶無需關心它的請求是哪個處理者來處理,反正總有一個處理者會處理它的請求。
在這裡接收者和發送者都沒有對方明确的資訊,同時接收者也不知道職責鍊中的結構。是以職責鍊可以簡化對象的互相連接配接,他們隻需要儲存一個指向其後續者的引用,而不需要儲存所有候選者的引用。
在職責鍊模式中我們可以随時随地的增加或者更改一個處理請求的結構,甚至可以更改處理者的順序,增加了系統的靈活性。處理靈活性是增加了,但是有時候可能會導緻一個請求無論如何也得不到處理,它會被放置在鍊末端,這個既是職責鍊的優點也是缺點。
模式結構
模式實作
處理請示的接口
package com.bjsxt.chainOfResp;
/**
* 抽象類
* @author Administrator
*
*/
public abstract class Leader {
protected String name;
protected Leader nextLeader;//責任鍊上的後繼對象
public Leader(String name) {
super();
this.name = name;
}
//設定責任鍊後繼對象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 處理請求的核心的業務方法
* @param request
*/
public abstract void handleRequest(LeaveRequest request);
}
總經理
package com.bjsxt.chainOfResp;
/**
* 總經理
* @author Administrator
*
*/
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 30){
System.out.println("員工"+request.getEmpName()+"請假 天數"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("總經理:"+this.name+"審批通過");
}else{
System.out.println("莫非"+request.getEmpName()+"想辭職 居然請假"+request.getLeaveDays()+"天");
}
}
}
副總經理
package com.bjsxt.chainOfResp;
/**
* 副總經理
* @author Administrator
*
*/
public class ViceGeneralManager extends Leader {
public ViceGeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 20){
System.out.println("員工"+request.getEmpName()+"請假 天數"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("副總經理:"+this.name+"審批通過");
}else{
this.nextLeader.handleRequest(request);
}
}
}
經理
package com.bjsxt.chainOfResp;
/**
* 經理
* @author Administrator
*
*/
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 10){
System.out.println("員工"+request.getEmpName()+"請假 天數"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("經理:"+this.name+"審批通過");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
主任
package com.bjsxt.chainOfResp;
/**
* 主任
* @author Administrator
*
*/
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays() < 3){
System.out.println("員工"+request.getEmpName()+"請假 天數"+request.getLeaveDays()+"理由:"+request.getReason());
System.out.println("主任:"+this.name+"審批通過");
}else{
if(this.nextLeader != null){
this.nextLeader.handleRequest(request);
}
}
}
}
申請
package com.bjsxt.chainOfResp;
/**
* 封裝請假基本資訊
* @author Administrator
*
*/
public class LeaveRequest {
private String empName;
private int leaveDays;
private String reason;
public LeaveRequest(String empName, int leaveDays, String reason) {
super();
this.empName = empName;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
測試類
package com.bjsxt.chainOfResp;
public class Client {
public static void main(String[] args) {
Leader a = new Director("張三");
Leader b = new Manager("李四");
Leader b2 = new ViceGeneralManager("李小四");
Leader c = new GeneralManager("王五");
//組織責任鍊對象關系
a.setNextLeader(b);
b.setNextLeader(b2);
b2.setNextLeader(c);
//開始請假操作
LeaveRequest req1 = new LeaveRequest("Tom", 10, "回英國老家");
a.handleRequest(req1);
}
}
使用場景
1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運作時刻自動确定。
2、在不明确指定接收者的情況下,向多個對象中的一個送出一個請求。
3、可動态指定一組對象處理請求。
模式優缺點
優點
1、降低耦合度。它将請求的發送者和接受者解耦。
2、簡化了對象。使得對象不需要知道鍊的結構。
3、增強給對象指派職責的靈活性。通過改變鍊内的成員或者調動它們的次序,允許動态地新增或者删除責任。
4、增加新的請求處理類很友善。
缺點
1、不能保證請求一定被接收。
2、系統性能将受到一定影響,而且在進行代碼調試時不太友善;可能會造成循環調用。
3、可能不容易觀察運作時的特征,有礙于除錯。
模式總結
1、職責鍊模式将請求的發送者和接受者解耦了。用戶端不需要知道請求處理者的明确資訊,甚至不需要知道鍊的結構,它隻需要将請求進行發送即可。
2、職責鍊模式能夠非常友善的動态增加新職責或者删除職責。
3、用戶端發送的請求可能會得不到處理。
4、處理者不需要知道鍊的結構,隻需要明白他的後續者是誰就可以了。這樣就簡化了系統中的對象。