摘要:安全式組合模式中的抽象構件不聲明管理子類的接口,把操作移交給子類完成。組合模式實現(xiàn)樣例使用組合模式實現(xiàn)目錄和課程之間的關系。
0x01.定義與類型
定義:將對象組合成樹形結構以表示“部分-整體”的層次結構,使客戶端對單個對象和組合對象保持一致的方式處理
組合模式實現(xiàn)的最關鍵的地方是:簡單對象和復合對象必須實現(xiàn)相同的接口,這就是組合模式能夠將組合對象和簡單對象進行一致處理的原因。
類型:結構型
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; } }
測試與應用類
/** * 應用與測試 */ 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(); } }
輸入結果
樹 樹葉4 樹葉5 樹枝1 樹枝1樹葉1 樹枝1樹葉2 樹枝1樹葉3
組合模式中的透明式以及安全式
透明式:組合模式中的抽象構件還聲明訪問和管理子類的接口,客戶端使用的適合不需要區(qū)分葉子節(jié)點和樹枝節(jié)點,但是葉子節(jié)點本身并不存在操作方法,一般會給出默認實現(xiàn),比如拋出異常。
安全式:組合模式中的抽象構件不聲明管理子類的接口,把操作移交給子類完成。這樣葉子節(jié)點不需要實現(xiàn)操作方法,但是客戶端使用時必須做出區(qū)分,為使用帶來麻煩。
上面的方式中使用的是安全模式。
組合模式中的角色
抽象構件(Component)角色:它的主要作用是為樹葉構件和樹枝構件聲明公共接口,并實現(xiàn)它們的默認行為。在透明式的組合模式中抽象構件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由樹枝構件完成。
樹葉構件(Leaf)角色:是組合中的葉節(jié)點對象,它沒有子節(jié)點,用于實現(xiàn)抽象構件聲明的公共接口。
樹枝構件(Composite)角色:是組合中的分支節(jié)點對象,它有子節(jié)點。它實現(xiàn)了抽象構件角色中聲明的接口,它的主要作用是存儲和管理子部件,通常包含 add()、remove()、get() 等方法。
0x02.適用場景希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結構中的所有對象時。
當想表達對象的部分-整體的層次結構時。
0x03.優(yōu)點清楚地定義分層次的復雜對象,表示對象的全部或部分層次
組合模式使得客戶端代碼可以一致地處理對象和對象容器,無需關心處理的單個對象,還是組合的對象容器。
簡化客戶端代碼
符合開閉原則
0x04.缺點限制類型時會較為復雜。
使設計變得更加抽象,客戶端需要花更多時間理清類之間的層次關系。
0x05.組合模式實現(xiàn)樣例使用組合模式實現(xià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); } }
測試與應用
/** * 測試與應用 */ 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設計模式", 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.相關設計模式
組合模式和訪問者模式
可以適用訪問者模式來訪問組合模式中的遞歸結構
0x07.源碼中的組合模式java.awt.Container
HashMap.putAll
ArrayList.addAll
MyBatis.SqlNode
0x08.代碼地址設計模式之組合模式:https://github.com/sigmako/design-pattern/tree/master/composite
0x09.參考慕課網設計模式精講: https://coding.imooc.com/class/270.html
組合模式(詳解版): http://c.biancheng.net/view/1373.html
設計模式之組合模式: https://www.cnblogs.com/snaildev/p/7647190.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://www.ezyhdfw.cn/yun/76031.html
摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當的實現(xiàn)方式原文地址是每天一個設計模式之組合模式歡迎關注個人技術博客。 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當的實現(xiàn)方式 ...
摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現(xiàn)。誠然,每種設計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當的實現(xiàn)方式原文地址是每天一個設計模式之組合模式歡迎關注個人技術博客。 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現(xiàn)。誠然,每種設計模式都有多種實現(xiàn)方式,但此小冊只記錄最直截了當的實現(xiàn)方式 ...
摘要:什么是組合模式什么是組合模式組合模式將對象組合成樹形結構以表示部分整體的層次結構,使得用戶對單個對象和組合對象的使用具有一致性。組合模式應用場景組合模式應用場景只要是樹形結構,就可以考慮使用組合模式。1、什么是組合模式?Compose objects into tree structures to represent part-whole hierarchies.Composite lets...
摘要:享元模式通過分析應用程序的對象,將其解析為內在數據和外在數據,減少對象數量,從而提高程序的性能。通過這種方式進行事件綁定,可以減少事件處理程序的數量,這種方式叫做事件委托,也是運用了享元模式的原理。事件處理程序是公用的內在部分,每個菜單項各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript設計模式之外觀模式 概念 外觀模式:為一組復雜子系統(tǒng)接口提...
閱讀 3165·2023-04-25 18:54
閱讀 2665·2021-11-02 14:40
閱讀 3276·2021-09-23 11:58
閱讀 2490·2019-08-30 13:50
閱讀 1289·2019-08-29 12:46
閱讀 3177·2019-08-28 17:51
閱讀 733·2019-08-26 11:47
閱讀 954·2019-08-23 16:17