我們的KFG餐廳非常的big,非常的有逼格。
但是我們這裏帶來一個問題,你作爲CEO是不可能管理本集團內所有人的。
遙想當初我們倖幸苦苦開了第一家店,那個時候 你作爲店長 管理着手下不多的幾個員工。
然後我們在有了第二家店,第三家,在某個城市 你作爲這個城市的負責人 管理下屬的所有員工。
然後我們公司越來越大,已經在華北地區形成了不小的影響,而你作爲整個華北地區的負責人,管理着個個城市的負責人。
隨着我們的共同努力,公司稱霸全國。而你作爲ceo則是管理各個地區的負責人。
好了現在問題來了,要解決上述這種樹形結構的員工管理樹,該如何實現。
注意我這裏用圓角方框 和方框 將以上的員工 分成兩類,一類是 管理人員(圓角方框),另外一類則是我們的標準的普通員工,它們都是員工,ceo也不例外,要說ceo爲誰打工,爲了自己唄。
abstract class Staff {
private String name;
private String postion;
public Staff(String name, String postion) {
this.name = name;
this.postion = postion;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPostion() {
return postion;
}
public void setPostion(String postion) {
this.postion = postion;
}
abstract public void doWork();
public void hireStaff(Staff staff) {
}
public void fireStaff(Staff staff) {
}
}
class Magnager extends Staff {
private List<Staff> staffs = new LinkedList<>();
public Magnager(String name, String postion) {
super(name, postion);
}
@Override
public void doWork() {
System.out.println("im counting sheet.");
}
@Override
public void hireStaff(Staff staff) {
staffs.add(staff);
}
@Override
public void fireStaff(Staff staff) {
staffs.remove(staff);
}
}
class NormalStaff extends Staff {
public NormalStaff(String name, String postion) {
super(name, postion);
// TODO Auto-generated constructor stub
}
@Override
public void doWork() {
System.out.println("im doing some work.");
}
}
這樣我們就可以管理多級員工的問題了。當然你要說你既擔任ceo,同時管理 負責人 和普通員工 都是沒有任何問題的。
public class Composite {
public static void main(String[] args) {
//我們的ceo 出場了
Staff ceo = new Magnager("HeapStackk", "ceo");
//但是隻有ceo 我們不就成了光桿司令,所以我們得找到一個華東地區負責人
Staff huaDongAreaDirector = new Magnager("huadong", "director");
ceo.hireStaff(huaDongAreaDirector);
//華東地區負責人說,不行 我也要找人幫我打下手
Staff nanjingAreaDirector = new Magnager("nanjing", "director");
huaDongAreaDirector.hireStaff(nanjingAreaDirector);
//然後南京的負責人 就僱傭了一名店長…… 然後店長管理其員工
Staff KFGDianZhang = new Magnager("dianzhang", "dianzhang");
nanjingAreaDirector.hireStaff(KFGDianZhang);
//我們的南京負責人 表示對店長不滿意 所以我要炒你魷魚
nanjingAreaDirector.fireStaff(KFGDianZhang);
//我們的ceo表示 好無聊,不如我也自己直接參與一家店 做一個店長 僱傭人吧。
Staff cleaner = new NormalStaff("haha", "cleaner");
ceo.hireStaff(cleaner);
}
}
縱觀上述過程,我們需要將該種設計模式抽象出來,使的具有通性。
構建模式的組成
抽象構件角色(component):是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行爲。聲明一個接口用於訪問和管理Component子部件。這個接口可 以用來管理所有的子對象。(可選)在遞歸結構中定義一個接口,用於訪問一個父部件,並在合適的情況下實現它。
樹葉構件角色(Leaf):在組合樹中表示葉節點對象,葉節點沒有子節點。並在組合中定義圖元對象的行爲。
樹枝構件角色(Composite):定義有子部件的那些部件的行爲。存儲子部件。在Component接口中實現與子部件有關的操作。
客戶角色(Client):通過component接口操縱組合部件的對象。
在上述例子中:
抽象構建角色:Staff 無論是管理者 還是普通的員工都是員工。提供了管理員工的接口。
樹葉構建角色:NormalStaff 實際上並沒有子節點,雖然提供了僱用方法,然並沒什麼卵用。
樹枝構建角色:Manager 能夠存儲子部件,就是手下多少個員工。
客戶角色:這個裏面並沒有明確。
效果
1) • 定義了包含基本對象和組合對象的類層次結構 基本對象可以被組合成更復雜的組合對象,而這個組合對象又可以被組合,這樣不斷的遞歸下去。客戶代碼中,任何用到 基本對象的地方都可以使用組合對象。
2) • 簡化客戶代碼 客戶可以一致地使用組合結構和單個對象。通常用戶不知道 (也不關心)處理的是一個葉節點還是一個組合組件。這就簡化了客戶代碼 , 因爲在定義組合的那些類中不需要寫一些充斥着選擇語句的函數。
3) • 使得更容易增加新類型的組件 新定義的Composite或Leaf子類自動地與已有的結構和客戶代碼一起工作,客戶程序不需因新的Component類而改變。
4) • 使你的設計變得更加一般化 容易增加新組件也會產生一些問題,那就是很難限制組合中的組件。有時你希望一個組合只能有某些特定的組件。使用Composite時,你不能依賴類型系統施加這些約束,而必須在運行時刻進行檢查。
適用性
以下情況下適用Composite模式:
1).你想表示對象的部分-整體層次結構
2).你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。
spring中暫時未讀到疑似composite設計模式的代碼案例。