組合模式

參考
設(shè)計模式讀書筆記-----組合模式
C++設(shè)計模式——組合模式
Javascript設(shè)計模式理論與實戰(zhàn):組合模式

我們平時開發(fā)過程中,一定會遇到這種情況:同時處理簡單對象和由簡單對象組成的復雜對象,這些簡單對象和復雜對象會組合成樹形結(jié)構(gòu),在客戶端對其處理的時候要保持一致性。比如電商網(wǎng)站中的產(chǎn)品訂單,每一張產(chǎn)品訂單可能有多個子訂單組合,比如操作系統(tǒng)的文件夾,每個文件夾有多個子文件夾或文件,我們作為用戶對其進行復制,刪除等操作時,不管是文件夾還是文件,對我們操作者來說是一樣的。在這種場景下,就非常適合使用組合模式來實現(xiàn)。

一、基本知識

組合模式:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對單個對象和組合對象的使用具有一致性。
組合模式主要有三個角色:
(1)抽象組件(Component):抽象類,主要定義了參與組合的對象的公共接口
(2)子對象(Leaf):組成組合對象的最基本對象
(3)組合對象(Composite):由子對象組合起來的復雜對象
理解組合模式的關(guān)鍵是要理解組合模式對單個對象和組合對象使用的一致性,我們接下來說說組合模式的實現(xiàn)加深理解。

二、文件夾和文件的例子
Paste_Image.png
//文件類:File.java
public abstract class File {
    String name;
    
    public File(String name){
        this.name = name;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void display();
}

//文件夾類:Folder.java,該類包含對文件的增加、刪除和瀏覽三個方法
public class Folder extends File{
    private List<File> files;
    
    public Folder(String name){
        super(name);
        files = new ArrayList<File>();
    }
    
    /**
     * 瀏覽文件夾中的文件
     */
    public void display() {
        for(File file : files){
            file.display();
        }
    }
    
    /**
     * @desc 向文件夾中添加文件
     * @param file
     * @return void
     */
    public void add(File file){
        files.add(file);
    }
    
    /**
     * @desc 從文件夾中刪除文件
     * @param file
     * @return void
     */
    public void remove(File file){
        files.remove(file);
    }
}

//然后是三個文件類:TextFile.java、ImageFile.java、VideoFile.java
public class TextFile extends File{

    public TextFile(String name) {
        super(name);
    }

    public void display() {
        System.out.println("這是文本文件,文件名:" + super.getName());
    }
    
}

public class ImagerFile extends File{

    public ImagerFile(String name) {
        super(name);
    }

    public void display() {
        System.out.println("這是圖像文件,文件名:" + super.getName());
    }

}

public class VideoFile extends File{

    public VideoFile(String name) {
        super(name);
    }

    public void display() {
        System.out.println("這是影像文件,文件名:" + super.getName());
    }

}

//最后是客戶端
public class Client {
    public static void main(String[] args) {
        /**
         * 我們先建立一個這樣的文件系統(tǒng)
         *                  總文件
         *                  
         *   a.txt    b.jpg                   c文件夾              
         *                      c_1.text  c_1.rmvb    c_1.jpg   
         *                                                       
         */ 
        //總文件夾
        Folder zwjj = new Folder("總文件夾");
        //向總文件夾中放入三個文件:1.txt、2.jpg、1文件夾
        TextFile aText= new TextFile("a.txt");
        ImagerFile bImager = new ImagerFile("b.jpg");
        Folder cFolder = new Folder("C文件夾");
        
        zwjj.add(aText);
        zwjj.add(bImager);
        zwjj.add(cFolder);
        
        //向C文件夾中添加文件:c_1.txt、c_1.rmvb、c_1.jpg 
        TextFile cText = new TextFile("c_1.txt");
        ImagerFile cImage = new ImagerFile("c_1.jpg");
        VideoFile cVideo = new VideoFile("c_1.rmvb");
        
        cFolder.add(cText);
        cFolder.add(cImage);
        cFolder.add(cVideo);
        
        //遍歷C文件夾
        cFolder.display();
        //將c_1.txt刪除
        cFolder.remove(cText);
        System.out.println("-----------------------");
        cFolder.display();
    }
}

優(yōu)點
1、可以清楚地定義分層次的復雜對象,表示對象的全部或部分層次,使得增加新構(gòu)件也更容易。
2、客戶端調(diào)用簡單,客戶端可以一致的使用組合結(jié)構(gòu)或其中單個對象。
3、定義了包含葉子對象和容器對象的類層次結(jié)構(gòu),葉子對象可以被組合成更復雜的容器對象,而這個容器對象又可以被組合,這樣不斷遞歸下去,可以形成復雜的樹形結(jié)構(gòu)。
4、更容易在組合體內(nèi)加入對象構(gòu)件,客戶端不必因為加入了新的對象構(gòu)件而更改原有代碼。

缺點
1、使設(shè)計變得更加抽象,對象的業(yè)務(wù)規(guī)則如果很復雜,則實現(xiàn)組合模式具有很大挑戰(zhàn)性,而且不是所有的方法都與葉子對象子類都有關(guān)聯(lián)

**模式適用場景 **
1、需要表示一個對象整體或部分層次,在具有整體和部分的層次結(jié)構(gòu)中,希望通過一種方式忽略整體與部分的差異,可以一致地對待它們。
2、讓客戶能夠忽略不同對象層次的變化,客戶端可以針對抽象構(gòu)件編程,無須關(guān)心對象層次結(jié)構(gòu)的細節(jié)。

模式總結(jié)
1、 組合模式用于將多個對象組合成樹形結(jié)構(gòu)以表示“整體-部分”的結(jié)構(gòu)層次。組合模式對單個對象(葉子對象)和組合對象(容器對象)的使用具有一致性。
2、 組合對象的關(guān)鍵在于它定義了一個抽象構(gòu)建類,它既可表示葉子對象,也可表示容器對象,客戶僅僅需要針對這個抽象構(gòu)建進行編程,無須知道他是葉子對象還是容器對象,都是一致對待。
3、 組合模式雖然能夠非常好地處理層次結(jié)構(gòu),也使得客戶端程序變得簡單,但是它也使得設(shè)計變得更加抽象,而且也很難對容器中的構(gòu)件類型進行限制,這會導致在增加新的構(gòu)件時會產(chǎn)生一些問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是組合模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 優(yōu)點和缺點 適用環(huán)境 模式應(yīng)用 一、...
    w1992wishes閱讀 1,036評論 0 2
  • 1 場景問題# 1.1 商品類別樹## 考慮這樣一個實際的應(yīng)用:管理商品類別樹。 在實現(xiàn)跟商品有關(guān)的應(yīng)用系統(tǒng)的時候...
    七寸知架構(gòu)閱讀 6,312評論 10 59
  • 組合多個對象形成樹形結(jié)構(gòu)以表示具有“整體—部分”關(guān)系的層次結(jié)構(gòu)。組合模式對單個對象(即葉子對象)和組合對象(即容器...
    lyu571閱讀 558評論 0 1
  • 繼承是is-a的關(guān)系。組合和聚合有點像,有些書上沒有作區(qū)分,都稱之為has-a,有些書上對其進行了較為嚴格區(qū)分,組...
    時待吾閱讀 507評論 0 1
  • 組合模式的設(shè)計動機:組合模式定義了如何將容器對象和葉子對象進行遞歸組合,使得客戶在使用的過程中無須進行區(qū)分,可以對...
    stepanoval閱讀 605評論 0 0

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