設(shè)計(jì)模式-COMPOSITE(組合模式)

代碼示例:https://github.com/elfc/patterns

分類

類對(duì)象結(jié)構(gòu)型

意圖

將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)。Composite使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

動(dòng)機(jī)

Composite模式允許創(chuàng)建樹型層次結(jié)構(gòu)來改變復(fù)雜性,同時(shí)允許結(jié)構(gòu)中的每一個(gè)元素操作同一個(gè)接口。該模式將對(duì)象組合成樹型結(jié)構(gòu)來表示整個(gè)或部分的層次結(jié)構(gòu)。這就意味著Composite模式允許客戶端使用單個(gè)對(duì)象或多個(gè)同一對(duì)象的組合。

適用性

  • 想要表示對(duì)象的整個(gè)或者部分的層次結(jié)構(gòu)
  • 想要客戶端能夠忽略符合對(duì)象和單個(gè)對(duì)象之間的差異。
  • 結(jié)構(gòu)可以具有任何級(jí)別的復(fù)雜性,而且是動(dòng)態(tài)的。

優(yōu)點(diǎn)

  • 定義了由主要對(duì)象和復(fù)合對(duì)象組成的類層次結(jié)構(gòu)。
  • 使得添加新的組件類型更加簡(jiǎn)單。
  • 提供了結(jié)構(gòu)的靈活性和可管理的接口。

結(jié)構(gòu)

參與者

  • Component(GraphicComponent)
    -- 為組合中的對(duì)象聲明接口。
    -- 在適當(dāng)?shù)那闆r下,實(shí)現(xiàn)所有類共有接口的缺省行為。
    -- 聲明一個(gè)接口用于訪問和管理Component的子組件。
    -- (可選)在遞歸結(jié)構(gòu)中定義一個(gè)接口,用于訪問一個(gè)父部件,并在合適的情況下實(shí)現(xiàn)它。
  • Leaf(LineLeaf、RectangleLeaf、TextLeaf)
    -- 在組合中表示葉節(jié)點(diǎn)對(duì)象,葉結(jié)點(diǎn)沒有子結(jié)點(diǎn)。
    -- 在組合中定義圖元對(duì)象的行為。
  • Composite(PictureComposite)
    -- 定義有子部件的那些部件的行為。
    -- 存儲(chǔ)子部件。
    -- 在Component接口中實(shí)現(xiàn)與子部件有關(guān)的操作。
  • Client
    -- 通過Component接口操縱組合部件的對(duì)象。

代碼示例

  • 以下為透明模式的代碼示例
  • 示例假設(shè)在繪圖編輯器和圖形捕捉系統(tǒng)這樣的圖形應(yīng)用程序中,用戶可以使用簡(jiǎn)單的組件創(chuàng)建復(fù)雜的圖表。
  • Picture類定義了一個(gè)Graphic對(duì)象的聚合。Picture的Draw操作是通過對(duì)它的子部件調(diào)用Draw實(shí)現(xiàn)的,Picture還用這種方法實(shí)現(xiàn)了一些與其子部件相關(guān)的操作。由于Picture接口與Graphic接口是一致的,因此Picture對(duì)象可以遞歸地組合其他Picture對(duì)象。

/**
 * @author chunyuliu
 */
public abstract class GraphicComponent {

    /**
     * 葉子及組合結(jié)點(diǎn)都實(shí)現(xiàn)的方法
     */
    public abstract void draw();

    /**
     * 添加葉子結(jié)點(diǎn)方法
     * 透明模式葉子結(jié)點(diǎn)不需要實(shí)現(xiàn)add方法, 默認(rèn)實(shí)現(xiàn)
     * @param graphicComponent
     */
    public void add(GraphicComponent graphicComponent) {
        throw new UnsupportedOperationException("Object UnsupportedOperation add method");
    }

    /**
     * 刪除葉子結(jié)點(diǎn)方法
     * 透明模式葉子結(jié)點(diǎn)不需要實(shí)現(xiàn)remove方法, 默認(rèn)實(shí)現(xiàn)
     * @param graphicComponent
     */
    public void remove(GraphicComponent graphicComponent) {
        throw new UnsupportedOperationException("Object UnsupportedOperation remove method");
    }

    /**
     * 獲取葉子結(jié)點(diǎn)方法
     * @param index 葉子結(jié)點(diǎn)索引
     * @return
     */
    public GraphicComponent getChild(int index) {
        throw new UnsupportedOperationException("Object UnsupportedOperation getChild method");
    }
}
/**
 * @author chunyuliu
 */
public class LineLeaf extends GraphicComponent {

    @Override
    public void draw() {
        System.out.println("LineLeaf draw");
    }
}
/**
 * @author chunyuliu
 */
public class RectangleLeaf extends GraphicComponent {

    @Override
    public void draw() {
        System.out.println("RectangleLeaf draw");
    }
}
/**
 * @author chunyuliu
 */
public class TextLeaf extends GraphicComponent {

    @Override
    public void draw() {
        System.out.println("TextLeaf draw");
    }
}
/**
 * @author chunyuliu
 */
public class PictureComposite extends GraphicComponent {

    private List<GraphicComponent> childList = new ArrayList<GraphicComponent>();

    @Override
    public void add(GraphicComponent graphicComponent) {
        childList.add(graphicComponent);
    }

    @Override
    public void remove(GraphicComponent graphicComponent) {
        childList.remove(graphicComponent);
    }

    @Override
    public void draw() {
        System.out.println("PictureComposite");
        if (childList != null && childList.size() > 0) {
            for (GraphicComponent graphicComponent : childList) {
                graphicComponent.draw();
            }
        }
    }

    @Override
    public GraphicComponent getChild(int index) {
        if (childList == null || childList.size() <= index) {
            return null;
        }

        return childList.get(index);
    }
}

測(cè)試用例

/**
 * @author chunyuliu
 */
public class CompositeTest {

    @Test
    public void graphicTest() {
        // 子部件
        GraphicComponent pictureComposite = new PictureComposite();
        // 組合葉子部件
        pictureComposite.add(new LineLeaf());
        pictureComposite.add(new RectangleLeaf());
        pictureComposite.add(new TextLeaf());
        GraphicComponent subPictureComposite = new PictureComposite();
        subPictureComposite.add(new LineLeaf());
        subPictureComposite.add(new RectangleLeaf());
        subPictureComposite.add(new TextLeaf());

        pictureComposite.add(subPictureComposite);

        pictureComposite.draw();

        // 獲取葉子結(jié)點(diǎn)
        System.out.println("RectangleLeaf: " + pictureComposite.getChild(1));
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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