摘要:安全式組合模式中的抽象構(gòu)件不聲明管理子類的接口,把操作移交給子類完成。組合模式實現(xiàn)樣例使用組合模式實現(xiàn)目錄和課程之間的關(guān)系。
0x01.定義與類型
定義:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使客戶端對單個對象和組合對象保持一致的方式處理
組合模式實現(xiàn)的最關(guān)鍵的地方是:簡單對象和復(fù)合對象必須實現(xiàn)相同的接口,這就是組合模式能夠?qū)⒔M合對象和簡單對象進行一致處理的原因。
類型:結(jié)構(gòu)型
UML類圖
Java實現(xiàn)
/** * 組合模式統(tǒng)一接口類 */ public interface Component { void operation(); } /** * 組合類 */ public class Composite implements Component { private String name; private Listcomponents = new ArrayList<>(); public Composite(String name) { this.name = name; } public void add(Component component) { components.add(component); } public void remove (Component component) { components.remove(component); } public Component get(int index) { return components.get(index); } @Override public void operation() { System.out.println(this.name); for (Component component : components) { component.operation(); } } } /** * 簡單類 */ public class Leaf implements Component { private String name; public Leaf(String name) { this.name = name; } @Override public void operation() { System.out.println(this.name); } public String getName() { return name; } }
測試與應(yīng)用類
/** * 應(yīng)用與測試 */ public class Test { public static void main(String[] args) { Composite composite = new Composite("樹枝1"); Leaf leaf1 = new Leaf("樹枝1樹葉1"); Leaf leaf2 = new Leaf("樹枝1樹葉2"); Leaf leaf3 = new Leaf("樹枝1樹葉3"); composite.add(leaf1); composite.add(leaf2); composite.add(leaf3); Composite composite1 = new Composite("樹"); Leaf leaf4 = new Leaf("樹葉4"); Leaf leaf5 = new Leaf("樹葉5"); composite1.add(leaf4); composite1.add(leaf5); composite1.add(composite); composite1.operation(); } }
輸入結(jié)果
樹 樹葉4 樹葉5 樹枝1 樹枝1樹葉1 樹枝1樹葉2 樹枝1樹葉3
組合模式中的透明式以及安全式
透明式:組合模式中的抽象構(gòu)件還聲明訪問和管理子類的接口,客戶端使用的適合不需要區(qū)分葉子節(jié)點和樹枝節(jié)點,但是葉子節(jié)點本身并不存在操作方法,一般會給出默認實現(xiàn),比如拋出異常。
安全式:組合模式中的抽象構(gòu)件不聲明管理子類的接口,把操作移交給子類完成。這樣葉子節(jié)點不需要實現(xiàn)操作方法,但是客戶端使用時必須做出區(qū)分,為使用帶來麻煩。
上面的方式中使用的是安全模式。
組合模式中的角色
抽象構(gòu)件(Component)角色:它的主要作用是為樹葉構(gòu)件和樹枝構(gòu)件聲明公共接口,并實現(xiàn)它們的默認行為。在透明式的組合模式中抽象構(gòu)件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由樹枝構(gòu)件完成。
樹葉構(gòu)件(Leaf)角色:是組合中的葉節(jié)點對象,它沒有子節(jié)點,用于實現(xiàn)抽象構(gòu)件聲明的公共接口。
樹枝構(gòu)件(Composite)角色:是組合中的分支節(jié)點對象,它有子節(jié)點。它實現(xiàn)了抽象構(gòu)件角色中聲明的接口,它的主要作用是存儲和管理子部件,通常包含 add()、remove()、get() 等方法。
0x02.適用場景希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象時。
當(dāng)想表達對象的部分-整體的層次結(jié)構(gòu)時。
0x03.優(yōu)點清楚地定義分層次的復(fù)雜對象,表示對象的全部或部分層次
組合模式使得客戶端代碼可以一致地處理對象和對象容器,無需關(guān)心處理的單個對象,還是組合的對象容器。
簡化客戶端代碼
符合開閉原則
0x04.缺點限制類型時會較為復(fù)雜。
使設(shè)計變得更加抽象,客戶端需要花更多時間理清類之間的層次關(guān)系。
0x05.組合模式實現(xiàn)樣例使用組合模式實現(xiàn)目錄和課程之間的關(guān)系。
因為上面給出的basic實現(xiàn)安全模式的,這次的樣例使用透明模式實現(xiàn)。
Java代碼
/** * 通用的抽象類 */ public abstract class CatalogComponent { public void add (CatalogComponent catalogComponent) { throw new UnsupportedOperationException("不支持添加操作"); } public void remove (CatalogComponent catalogComponent) { throw new UnsupportedOperationException("不支持刪除操作"); } public String getName () { throw new UnsupportedOperationException("不支持獲取名稱操作"); } public Double getPrice () { throw new UnsupportedOperationException("不支持獲取價錢操作"); } public void print () { throw new UnsupportedOperationException("不支持打印操作"); } } /** * 目錄 */ public class CourseCatalog extends CatalogComponent { private Listitsms = new ArrayList<>(); private String name; private Integer level; public CourseCatalog(String name, Integer level) { this.name = name; this.level = level; } @Override public String getName() { return this.name; } @Override public void add(CatalogComponent catalogComponent) { this.itsms.add(catalogComponent); } @Override public void remove(CatalogComponent catalogComponent) { this.itsms.remove(catalogComponent); } @Override public void print() { System.out.println("> " + this.name); for (CatalogComponent catalogComponent : itsms) { if (this.level != null) { for (int i = 0; i < this.level; i ++) { System.out.print("--"); } } catalogComponent.print(); } } } /** * 具體的課程 */ public class Course extends CatalogComponent { private String name; private Double price; public Course(String name, Double price) { this.name = name; this.price = price; } @Override public String getName() { return this.name; } @Override public Double getPrice() { return this.price; } @Override public void print() { System.out.println("> Course Name:" + this.name + ": price: " + this.price); } }
測試與應(yīng)用
/** * 測試與應(yīng)用 */ public class Test { public static void main(String[] args) { CatalogComponent linuxCourse = new Course("Linux課程", 11D); CatalogComponent windowCourse = new Course("Window課程", 12D); CatalogComponent javaCourseCatalog = new CourseCatalog("Java課程目錄", 2); CatalogComponent mmallCourse1 = new Course("Java電商一期", 55D); CatalogComponent mmallCourse2 = new Course("Java電商二期", 66D); CatalogComponent designPattern = new Course("Java設(shè)計模式", 77D); javaCourseCatalog.add(mmallCourse1); javaCourseCatalog.add(mmallCourse2); javaCourseCatalog.add(designPattern); CatalogComponent mainCourseCatalog = new CourseCatalog("課程主目錄", 1); mainCourseCatalog.add(linuxCourse); mainCourseCatalog.add(windowCourse); mainCourseCatalog.add(javaCourseCatalog); mainCourseCatalog.print(); } }
UML類圖
0x06.相關(guān)設(shè)計模式
組合模式和訪問者模式
可以適用訪問者模式來訪問組合模式中的遞歸結(jié)構(gòu)
0x07.源碼中的組合模式java.awt.Container
HashMap.putAll
ArrayList.addAll
MyBatis.SqlNode
0x08.代碼地址設(shè)計模式之組合模式:https://github.com/sigmako/design-pattern/tree/master/composite
0x09.參考慕課網(wǎng)設(shè)計模式精講: https://coding.imooc.com/class/270.html
組合模式(詳解版): http://c.biancheng.net/view/1373.html
設(shè)計模式之組合模式: https://www.cnblogs.com/snaildev/p/7647190.html
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76031.html
摘要:作者按每天一個設(shè)計模式旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當(dāng)?shù)膶崿F(xiàn)方式原文地址是每天一個設(shè)計模式之組合模式歡迎關(guān)注個人技術(shù)博客。 作者按:《每天一個設(shè)計模式》旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當(dāng)?shù)膶崿F(xiàn)方式 ...
摘要:作者按每天一個設(shè)計模式旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當(dāng)?shù)膶崿F(xiàn)方式原文地址是每天一個設(shè)計模式之組合模式歡迎關(guān)注個人技術(shù)博客。 作者按:《每天一個設(shè)計模式》旨在初步領(lǐng)會設(shè)計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設(shè)計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當(dāng)?shù)膶崿F(xiàn)方式 ...
摘要:什么是組合模式什么是組合模式組合模式將對象組合成樹形結(jié)構(gòu)以表示部分整體的層次結(jié)構(gòu),使得用戶對單個對象和組合對象的使用具有一致性。組合模式應(yīng)用場景組合模式應(yīng)用場景只要是樹形結(jié)構(gòu),就可以考慮使用組合模式。1、什么是組合模式?Compose objects into tree structures to represent part-whole hierarchies.Composite lets...
摘要:享元模式通過分析應(yīng)用程序的對象,將其解析為內(nèi)在數(shù)據(jù)和外在數(shù)據(jù),減少對象數(shù)量,從而提高程序的性能。通過這種方式進行事件綁定,可以減少事件處理程序的數(shù)量,這種方式叫做事件委托,也是運用了享元模式的原理。事件處理程序是公用的內(nèi)在部分,每個菜單項各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript設(shè)計模式之外觀模式 概念 外觀模式:為一組復(fù)雜子系統(tǒng)接口提...
摘要:橋接模式中的所謂脫耦,就是指在一個軟件系統(tǒng)的抽象化和實現(xiàn)化之間使用關(guān)聯(lián)關(guān)系組合或者聚合關(guān)系而不是繼承關(guān)系,從而使兩者可以相對獨立地變化,這就是橋接模式的用意。 0x01.定義與類型 定義:將抽象部分與它的具體實現(xiàn)部分分離,使它們都可以獨立地變化。 橋接模式將繼承關(guān)系轉(zhuǎn)化成關(guān)聯(lián)關(guān)系,它降低了類與類之間的耦合度,減少了系統(tǒng)中類的數(shù)量,也減少了代碼量。 橋接模式中的所謂脫耦,就是指在一個軟...
閱讀 3079·2023-04-25 18:54
閱讀 2598·2021-11-02 14:40
閱讀 3193·2021-09-23 11:58
閱讀 2438·2019-08-30 13:50
閱讀 1243·2019-08-29 12:46
閱讀 3129·2019-08-28 17:51
閱讀 687·2019-08-26 11:47
閱讀 907·2019-08-23 16:17