Java設計模式之-組合模式(Composite)

說起OO的特點,大家腦海中會立刻蹦出幾個詞:多態(tài)、繼承(is-a)、組合(has-a)。

其中組合既可以作為一個特性,也可以作為一種特定的設計模式,但在兩種場合中的含義有些區(qū)別。


OO特點------組合

當把現(xiàn)實世界的各種物體抽象為類之后,很自然地想到類與類之間還存在不同的關系。重要的兩種就是“is-a”"has-a"。其中"has-a"就表示了組合,即:

Class Macan extends Prosche{
    private Machine machine;
    private List<Tire> tires;
    private Framework framework; 
}

一輛macan首先是一輛保時捷(is-a),而一輛macan有一個車框架,一個發(fā)動機和多個輪子(has-a)。按照這一理念建立起來的類便體現(xiàn)了組合的思想。

下面我們再看看設計模式中的組合是如何實現(xiàn)的。


存在某種類A,它實現(xiàn)了接口I中定義的操作;另外存在類B,它表示了一個包含多個實現(xiàn)I接口的類的集合,且為了使B和它所包含的類的行為一致,B自身也應實現(xiàn)I接口。因此,B所包含的可能是A,也可能是另外一個或多個包含了A的B'


組合模式

這張圖中MachineComponent是一個虛擬類,而非接口,而Machine和MachineComposite均繼承了該類。另外在MachineComposite中還保存了一個MachineComponent的數(shù)組。這樣就已經(jīng)建立其了組合模式的基本結構。
但是在組合模式中需要特別關注的一點就是:是否有樹形結構,是否有環(huán)形結構。
還是看上圖的isTree函數(shù),來判斷當前是否是一個樹。

在MachineComponent中我們定義:

public boolean isTree(){
    return isTree(new HashSet<MachineComponent>());
}

protected abstract boolean isTree(Set<? extends MachineComponent> visited);

而在子類中,我們實現(xiàn)該isTree函數(shù):

protected boolean isTree(Set visited) {
    if (visited.contains(this)) return false;
    visited.add(this);
    for (MachineComponent m : components) {
        if (!m.isTree(visited)) return false;
    }
    return true;
}

可以發(fā)現(xiàn),在isTree我們維護了一個Set,以保證每一個元素只被訪問了一次。如果存在當前元素已經(jīng)在Set中的,isTree函數(shù)便會返回false.
判斷是否為樹結構非常重要,因為當我們對組合進行迭代遍歷時,很可能不允許某一個子類被遍歷多次。例如當前需要計算所有Machine的數(shù)量,如果有兩個組合使用了同一個Machine,在組合進行計數(shù)時便會將其計算兩次,這顯然與實際不符。

另外整個組合中是否有環(huán)也需要仔細考慮。如果A中有B,B中有C,C中又有A,這個時候如果對A進行類似計數(shù)的操作,很可能就會發(fā)生死循環(huán)。如果對其進行類似isTree中訪客記錄的處理,可以避免此問題。


綜上,組合包含了兩個主要的特性:

  1. 一個組合對象,可以包含對應的單個對象,也可以包含另一個合適的組合對象。
  2. 組合對象與單個對象應該實現(xiàn)共同的接口或繼承共同的虛類,以獲得相同的行為。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評論 19 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 1 場景問題# 1.1 商品類別樹## 考慮這樣一個實際的應用:管理商品類別樹。 在實現(xiàn)跟商品有關的應用系統(tǒng)的時候...
    七寸知架構閱讀 6,258評論 10 59
  • 醒來想起好久以前讀到季羨林老先生21歲時在德國留學期間夢到逝去的母親的一段話了:夜里夢到母親,我哭著醒來。醒來...
    西席閱讀 317評論 0 0
  • 她們總在說教 不是你不優(yōu)秀 而是想讓你更優(yōu)秀 當你成長時 你或許從來未看到 她們轉(zhuǎn)過臉嘴角的微笑 但是 這是真的 ...
    麥女神閱讀 531評論 0 0

友情鏈接更多精彩內(nèi)容