問題提出
小明想要請個假,但由於種種原因不得不一直向上層層傳遞到總經理。設請假的級別爲10。組長處理的級別爲1~5,經理處理的級別爲6~8,總經理處理的級別爲9~10。用代碼實現這個請假場景。
職責鏈模式
使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞改請求,直到有一個對象處理它爲止。
package chainofresponsibility;
public class ChainOfResponsibility {
public static void main(String[] args) {
//初始化三個人
Manager leader = new Leader();
Manager director = new Director();
Manager boss = new Boss();
//設置彼此之間的上下級關係
leader.setSuperManager(director);
director.setSuperManager(boss);
//處理小明請假的事情 等級爲10
leader.dealThings(10);
}
}
/**
* 管理者接口
*/
interface Manager {
//根據事情能級處理
void dealThings(int level);
void setSuperManager(Manager manager);
}
/**
* 組長
*/
class Leader implements Manager {
private Manager superManager;
//設置上級
@Override
public void setSuperManager(Manager manager) {
superManager = manager;
}
@Override
public void dealThings(int level) {
if (level < 5) {
System.out.println("組長成功處理事情");
} else {
//處理不了則上拋
superManager.dealThings(level);
}
}
}
/**
* 經理
*/
class Director implements Manager{
private Manager superManager;
//設置上級
@Override
public void setSuperManager(Manager manager) {
superManager = manager;
}
@Override
public void dealThings(int level) {
if (level < 8) {
System.out.println("經理成功處理事情");
} else {
//處理不了則上拋
superManager.dealThings(level);
}
}
}
class Boss implements Manager{
@Override
public void dealThings(int level) {
System.out.println("總經理成功處理事情");
}
@Override
public void setSuperManager(Manager manager) {
System.out.println("boss無上級");
}
}
輸出:
總經理成功處理事情
其實我感覺職責鏈模式的設計和裝飾模式有很多相似之處:都是定義一個接口然後在子類中保留該接口的引用。在deal()方法中調用這個引用的deal()方法。
只不過這兩者定義不同。裝飾模式側重在原實現類的基礎上進行其他實現類的層層包裝,而職責鏈模式則側重於自己是否該處理這個請求。處理不了才拋給另外一個實現類進行處理。
plantuml
@startuml
interface Manager{
{abstract}dealThings(int level);
{abstract}setSuperManager(Manager manager);
}
Manager <..* Leader
Manager <|.. Leader
class Leader{
Manager superManager
dealThings(int level);
setSuperManager(Manager manager);
}
Manager <..* Director
Manager <|.. Director
class Director{
Manager superManager
dealThings(int level);
setSuperManager(Manager manager);
}
Manager <..* Boss
Manager <|.. Boss
class Boss{
Manager superManager
dealThings(int level);
setSuperManager(Manager manager);
}
@enduml