簡(jiǎn)易理解設(shè)計(jì)模式之:組合模式——實(shí)現(xiàn)View中的樹(shù)狀結(jié)構(gòu)

介紹:

組合模式屬于結(jié)構(gòu)型模式。將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示‘部分-整體’的層次結(jié)構(gòu)。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

類圖:

組合模式UML類圖.png

Component(抽象組件角色):為組合中的對(duì)象聲明接口
Composite(樹(shù)枝節(jié)點(diǎn)):樹(shù)枝節(jié)點(diǎn)有子節(jié)點(diǎn),用來(lái)存儲(chǔ)子部件
Leaf(葉子節(jié)點(diǎn)):葉子節(jié)點(diǎn)沒(méi)有子節(jié)點(diǎn)

用法:

? 表示對(duì)象的部分-整體層次結(jié)構(gòu)時(shí)
? 從一個(gè)整體中能夠獨(dú)立出部分模塊或功能的場(chǎng)景

個(gè)人理解:


樹(shù)狀結(jié)構(gòu)圖.png

組合模式本質(zhì)就是樹(shù)狀結(jié)構(gòu)算法的實(shí)現(xiàn),它強(qiáng)調(diào)出部分與整體的層次結(jié)構(gòu),并且葉子節(jié)點(diǎn)和樹(shù)枝節(jié)點(diǎn)都必須實(shí)現(xiàn)相同的接口。例如目錄結(jié)構(gòu)、文件夾結(jié)構(gòu)、公司組織結(jié)構(gòu)等都是組合模式的一個(gè)應(yīng)用。

例子:

在GUI開(kāi)發(fā)中,有些視圖控件可以添加其它子視圖(ViewGroup),而有些卻不能添加(View)。ViewGroup與View在GUI開(kāi)發(fā)中是很經(jīng)典也很常用的組合模式。

需求:模擬View的實(shí)現(xiàn)

1、模擬View結(jié)構(gòu)的實(shí)現(xiàn)(第一版代碼)

1.1、創(chuàng)建抽象組件接口

public abstract class View {
    protected List<View> mViews = new ArrayList<>();
    protected String name;
    public View(String name){
        this.name = name;
    }

    public abstract void addView(View view);
    public abstract void removeView(View view);
    public abstract void printViews(String placeholder);
}

定義了三個(gè)抽象方法,分別讓葉子節(jié)點(diǎn)和樹(shù)枝節(jié)點(diǎn)實(shí)現(xiàn)該方法。

1.2、創(chuàng)建葉子節(jié)點(diǎn)ContentView

public class ContentView extends View {

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

    @Override
    public void addView(View view) {
        throw new UnsupportedOperationException("不支持此操作");
    }

    @Override
    public void removeView(View view) {
        throw new UnsupportedOperationException("不支持此操作");
    }

    @Override
    public void printViews(String placeholder) {
        System.out.println(placeholder + "--" + name);
    }
}

葉子節(jié)點(diǎn)作為整個(gè)樹(shù)狀結(jié)構(gòu)的最小單元,并沒(méi)有添加和刪除子View的方法。

1.3、創(chuàng)建樹(shù)枝節(jié)點(diǎn)ViewGroup

public class ViewGroup extends View {

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

    @Override
    public void addView(View view) {
        mViews.add(view);
    }

    @Override
    public void removeView(View view) {
        mViews.add(view);
    }

    @Override
    public void printViews(String placeholder) {
        System.out.println(placeholder + "└──" + name);
        for (View view : mViews) {
            view.printViews(placeholder+ "   ");
        }
    }
}

樹(shù)枝節(jié)點(diǎn)能夠刪除添加葉子或樹(shù)枝,實(shí)現(xiàn)了添加和刪除的方法。

1.4、使用和結(jié)果

public class Client {
    public static void main(String[] args) {
        //根節(jié)點(diǎn)
        View rootView = new ViewGroup("LinerLayout");

        //第一層-枝干節(jié)點(diǎn)
        View frameLayout = new ViewGroup("FrameLayout");

        //第二層-葉子節(jié)點(diǎn)
        View button = new ContentView("Button");
        View label = new ContentView("Label");

        //第一層-葉子節(jié)點(diǎn)
        View textView = new ContentView("TextView");

        rootView.addView(frameLayout);
        rootView.addView(textView);
        frameLayout.addView(button);
        frameLayout.addView(label);

        rootView.printViews("");
    }
}
└──LinerLayout
   └──FrameLayout
      --Button
      --Label
   --TextView

上面的例子中我們基本實(shí)現(xiàn)了需求。我們可以發(fā)現(xiàn),葉子節(jié)點(diǎn)不需要添加和刪除的方法,卻也同樣實(shí)現(xiàn)了抽象方法。這種方式,將使用的方法放到抽象類中,不管葉子對(duì)象還是樹(shù)枝對(duì)象都有相同的結(jié)構(gòu),成為透明組合模式

2、優(yōu)化View結(jié)構(gòu)的實(shí)現(xiàn)(第二版代碼)

在我們使用透明組合模式的時(shí)候,我們發(fā)現(xiàn)屬于葉子節(jié)點(diǎn)的ContentView并不需要實(shí)現(xiàn)如此多的方法。在組合模式有兩種不同的實(shí)現(xiàn),分別為透明組合模式安全組合模式

2.1、優(yōu)化View

public abstract class View {

    protected String name;

    public View(String name){
        this.name = name;
    }

    public abstract void printViews(String placeholder);

}

抽象方法中,將控制子View的方法放在ViewGorup中。

2.2、優(yōu)化ContentView

public class ContentView extends View {

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

    @Override
    public void printViews(String placeholder) {
        System.out.println(placeholder + "--" + name);
    }
}

ContentView只實(shí)現(xiàn)自己需要用到的方法。

2.3、優(yōu)化ViewGroup

public class ViewGroup extends View {

    protected List<View> mViews = new ArrayList<>();

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

    public void addView(View view) {
        mViews.add(view);
    }


    public void removeView(View view) {
        mViews.add(view);
    }

    @Override
    public void printViews(String placeholder) {
        System.out.println(placeholder + "└──" + name);
        for (View view : mViews) {
            view.printViews(placeholder+ "   ");
        }
    }
}

ViewGroup控制了子View的增刪操作。

2.4、客戶端代碼

public class Client {
    public static void main(String[] args) {
        //根節(jié)點(diǎn)
        ViewGroup rootView = new ViewGroup("LinerLayout");

        //第一層-枝干節(jié)點(diǎn)
        ViewGroup frameLayout = new ViewGroup("FrameLayout");

        //第二層-葉子節(jié)點(diǎn)
        ContentView button = new ContentView("Button");
        ContentView label = new ContentView("Label");

        //第一層-葉子節(jié)點(diǎn)
        ContentView textView = new ContentView("TextView");

        rootView.addView(frameLayout);
        rootView.addView(textView);
        frameLayout.addView(button);
        frameLayout.addView(label);

        rootView.printViews("");
    }
}

把樹(shù)枝節(jié)點(diǎn)和葉子節(jié)點(diǎn)的行為徹底分開(kāi),樹(shù)枝節(jié)點(diǎn)單獨(dú)擁有用來(lái)組合的方法,這種方式就是安全組合模式了。

總結(jié):

此模式本質(zhì)就是樹(shù)狀結(jié)構(gòu),在具有明顯的層次結(jié)構(gòu)時(shí)使用;組合模式分為安全組合模式透明組合模式,各有特點(diǎn)按實(shí)際開(kāi)發(fā)需求斟酌使用。

感謝您的閱讀~

轉(zhuǎn)載請(qǐng)注明出處喔:http://www.itdecent.cn/p/b55ddd99dfda

推薦閱讀

基礎(chǔ)篇:
設(shè)計(jì)模式前篇之——UML類圖必會(huì)知識(shí)點(diǎn)
設(shè)計(jì)模式前篇之——一起過(guò)一下面向?qū)ο蟮母拍?/a>
創(chuàng)建型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:簡(jiǎn)單工廠模式——來(lái)試試接入支付功能
簡(jiǎn)易理解設(shè)計(jì)模式之:工廠方法模式——數(shù)據(jù)存儲(chǔ)例子
簡(jiǎn)易理解設(shè)計(jì)模式之:抽象工廠模式——更換數(shù)據(jù)庫(kù)例子
簡(jiǎn)易理解設(shè)計(jì)模式之:建造者模式——學(xué)習(xí)使用“鏈?zhǔn)秸{(diào)用”
簡(jiǎn)易理解設(shè)計(jì)模式之:原型模式——深、淺拷貝的概念
簡(jiǎn)易理解設(shè)計(jì)模式之:?jiǎn)卫J健獑卫J降膸追N常用寫(xiě)法
結(jié)構(gòu)型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:適配器模式——Android列表視圖控件設(shè)計(jì)方式
簡(jiǎn)易理解設(shè)計(jì)模式之:橋接模式——穿衣服經(jīng)典案例2
簡(jiǎn)易理解設(shè)計(jì)模式之:組合模式——實(shí)現(xiàn)View中的樹(shù)狀結(jié)構(gòu)
簡(jiǎn)易理解設(shè)計(jì)模式之:裝飾模式——穿衣服經(jīng)典案例
簡(jiǎn)易理解設(shè)計(jì)模式之:外觀模式——第三方SDK的幫助類
簡(jiǎn)易理解設(shè)計(jì)模式之:享元模式——五子棋游戲例子
簡(jiǎn)易理解設(shè)計(jì)模式之:代理模式——iOS視圖控件設(shè)計(jì)方式
行為型模式:
簡(jiǎn)易理解設(shè)計(jì)模式之:策略模式——優(yōu)化一下支付功能
簡(jiǎn)易理解設(shè)計(jì)模式之:模板方法模式——Android中的BaseActivity基類
簡(jiǎn)易理解設(shè)計(jì)模式之:觀察者模式——監(jiān)聽(tīng)與回調(diào)
簡(jiǎn)易理解設(shè)計(jì)模式之:狀態(tài)模式——優(yōu)化登錄操作
簡(jiǎn)易理解設(shè)計(jì)模式之:備忘錄模式——Word文檔的工作原理
簡(jiǎn)易理解設(shè)計(jì)模式之:迭代器模式——遍歷對(duì)象的好幫手
簡(jiǎn)易理解設(shè)計(jì)模式之:命令模式——實(shí)現(xiàn)命令的參數(shù)化配置
簡(jiǎn)易理解設(shè)計(jì)模式之:責(zé)任鏈模式——OA中請(qǐng)假流程示例
簡(jiǎn)易理解設(shè)計(jì)模式之:中介者模式——多人聊天室例子
簡(jiǎn)易理解設(shè)計(jì)模式之:解釋器模式——語(yǔ)言和文法
簡(jiǎn)易理解設(shè)計(jì)模式之:訪問(wèn)者模式——員工考核例子

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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