為了防止被“殺”了祭天螃征,學(xué)點(diǎn)設(shè)計(jì)模式潮罪,并總結(jié)下還是有必要的寒砖。
一:理解
- 組合模式最普遍的例子就是文件系統(tǒng)和組織架構(gòu)谅猾。
- 一個(gè)對(duì)象可以看成是部分荐吵,多個(gè)對(duì)象以一定方式組合在一起是整體。在組合模式中赊瞬,部分和整體都用同一個(gè)類(lèi)表示先煎。
- 在組織架構(gòu)的例子中,組合模式把每個(gè)人都看作是一個(gè)組織巧涧,每個(gè)人都可以擁有自己的下屬薯蝎,同時(shí)每個(gè)下屬又都被看作是組織。
二:例子
你是個(gè)富二代谤绳。
你有很多女朋友占锯,然而你最近悶悶不樂(lè),生無(wú)可戀缩筛。
因?yàn)槟憧嘤谡也坏揭粋€(gè)管理那么多女朋友的好方法消略。
你決定效仿古代帝王,為你的女朋友們分等級(jí)瞎抛,等級(jí)高的女朋友可以有多個(gè)小妹艺演。
每次,你想papapa時(shí)桐臊,只需找到女朋友頭子胎撤,順著她的小妹網(wǎng)絡(luò),就可以找到所有女朋友断凶。
你被自己的高智商所折服伤提。
然而,你希望可以用更優(yōu)雅的辦法來(lái)抽象這個(gè)女朋友組織架構(gòu)认烁。
于是肿男,你叫來(lái)了程序員小菜幫忙介汹。
小菜上來(lái)就是一頓敲,他考慮到:
- 女友頭子所有管理多個(gè)小妹舶沛,但她和小妹其實(shí)沒(méi)什么區(qū)別痴昧,都是你的女朋友」谕酰可以用組合模式。
- 女朋友頭子的小妹可以用List保存舌镶。
@Data
public class GirlFriend {
private String name;
private List<GirlFriend> xiaoMeiList;
public GirlFriend(String name) {
xiaoMeiList = Lists.newArrayList();
this.name = name;
}
public void papapa() {
System.out.println("如果你追到" + name + "," + name + "就和你嘿嘿嘿!");
}
public void addXiaMei(GirlFriend girlFriend) {
xiaoMeiList.add(girlFriend);
}
public void remove(GirlFriend girlFriend) {
xiaoMeiList.remove(girlFriend);
}
public void continuousPapapa(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("--");
}
papapa();
for (GirlFriend xiaoMei : xiaoMeiList) {
xiaoMei.continuousPapapa(depth + 1);
}
}
}
女朋友類(lèi)GirlFriend包含屬性名字name屬性柱彻,包含小妹隊(duì)列屬性,隊(duì)列的類(lèi)型還是GirlFriend餐胀,因?yàn)樾∶靡彩桥笥选?/p>
女朋友類(lèi)中哟楷,有增加刪除小妹的方法。
此外否灾,還有一個(gè)continuousPapapa方法卖擅,你和一個(gè)女朋友papapa之后,你可以和她所有的小妹都papapa墨技。
是不是想想就覺(jué)得很激動(dòng)惩阶。
小菜寫(xiě)了一個(gè)測(cè)試程序給你看,除了模擬建立女朋友組織架構(gòu)的代碼之外扣汪,只需要調(diào)用女朋友頭子的continuousPapapa方法断楷。
public class Client {
public static void main(String[] args) {
GirlFriend TouZi = new GirlFriend("女朋友頭子");
// 一級(jí)
GirlFriend Mary = new GirlFriend("Mary");
GirlFriend Lily = new GirlFriend("Lily");
// 二級(jí)
GirlFriend MaryXiaoMei1 = new GirlFriend("MaryXiaoMei1");
GirlFriend MaryXiaoMei2 = new GirlFriend("MaryXiaoMei2");
GirlFriend LilyXiaoMei1 = new GirlFriend("LilyXiaoMei1");
// 三級(jí)
GirlFriend MaryXiaoMei1XiaoMei1 = new GirlFriend("MaryXiaoMei1XiaoMei1");
Mary.addXiaMei(MaryXiaoMei1);
Mary.addXiaMei(MaryXiaoMei2);
Lily.addXiaMei(LilyXiaoMei1);
MaryXiaoMei1.addXiaMei(MaryXiaoMei1XiaoMei1);
TouZi.addXiaMei(Mary);
TouZi.addXiaMei(Lily);
// 一步完成
TouZi.continuousPapapa(0);
}
}
輸入/輸出:
如果你追到女朋友頭子,女朋友頭子就和你嘿嘿嘿!
--如果你追到Mary,Mary就和你嘿嘿嘿!
----如果你追到MaryXiaoMei1,MaryXiaoMei1就和你嘿嘿嘿!
------如果你追到MaryXiaoMei1XiaoMei1,MaryXiaoMei1XiaoMei1就和你嘿嘿嘿!
----如果你追到MaryXiaoMei2,MaryXiaoMei2就和你嘿嘿嘿!
--如果你追到Lily,Lily就和你嘿嘿嘿!
----如果你追到LilyXiaoMei1,LilyXiaoMei1就和你嘿嘿嘿!
看到這個(gè)程序,你開(kāi)心到起飛崭别。
不僅可以做到優(yōu)雅的管理冬筒,而且可以擁有和古代帝王擁有一樣的享受。
三:再理解
- 組合模式茅主,將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)舞痰,組合模式使得用戶(hù)對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
- 組合模式中诀姚,類(lèi)的其中某個(gè)屬性引用了類(lèi)本身的對(duì)象响牛,做到部分和整體共用一個(gè)類(lèi)。