设计模式(结构型)之组合模式(Composite Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN。因为CSDN也支持MarkDown语法了,牛逼啊!

【工匠若水 】 阅读前一篇《设计模式(结构型)之桥接模式(Bridge Pattern)》

概述

组合模式又叫做部分-整体模式,使我们在树型结构的问题中模糊简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂的元素,从而使得客户程序与复杂元素的内部结构解耦。组合模式可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。

核心

概念: 组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。

重点: 组合模式结构重要核心模块:

抽象构件(Component)

组合中的对象声明接口,在适当的情况下实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

树叶构件(Leaf)

在组合中表示树的叶子结点对象,叶子结点没有子结点。

容器构件(Composite)

定义有枝节点的部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

核心:组合模式的关键是定义一个抽象构件类,它既可以代表Leaf,又可以代表Composite,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

使用场景

在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。

在一个使用面向对象语言开发的系统中需要处理一个树形结构。

在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

程序猿实例

假设问题环境:

就拿Android开发中最常见的一种情景来分析吧。我们有一种需求是遍历整个cache文件夹下的所有文件及文件夹,打印出来(实际指定不是打印,而是逻辑操作,这里演示而已)。如下我们先不使用组合模式。

package yanbober.github.io;import java.util.ArrayList;import java.util.List;class MediaFile {private String mName;private String mDescription;public MediaFile(String mName, String mDescription) {this.mName = mName;this.mDescription = mDescription;}@Overridepublic String toString() {return “MediaFile#hljs-string”>”, Description=”+mDescription;}}class OfficeFile {private String mName;private String mDescription;public OfficeFile(String mName, String mDescription) {this.mName = mName;this.mDescription = mDescription;}@Overridepublic String toString() {return “OfficeFile#hljs-string”>”, Description=”+mDescription;}}class PackageFile {private String mName;private String mDescription;public PackageFile(String mName, String mDescription) {this.mName = mName;this.mDescription = mDescription;}@Overridepublic String toString() {return “PackageFile#hljs-string”>”, Description=”+mDescription;}}class BaseFolder {private String mName;private String mDescription;private List<BaseFolder> mBaseFolderList = new ArrayList<>();private List<MediaFile> mMediaFileList = new ArrayList<>();private List<OfficeFile> mOfficeFileList = new ArrayList<>();private List<PackageFile> mPackageFileList = new ArrayList<>();public BaseFolder(String mName, String mDescription) {this.mName = mName;this.mDescription = mDescription;}(BaseFolder baseFolder) {mBaseFolderList.add(baseFolder);}(MediaFile mediaFile) {mMediaFileList.add(mediaFile);}(OfficeFile officeFile) {mOfficeFileList.add(officeFile);}(PackageFile packageFile) {mPackageFileList.add(packageFile);}@Overridepublic String toString() {StringBuilder builder = new StringBuilder(“*****BaseFolder# enter folder is:”+mName+”\n”);for (BaseFolder baseFolder : mBaseFolderList) {builder.append(baseFolder.toString()+”\n”);}for (MediaFile mediaFile : mMediaFileList) {builder.append(mediaFile.toString()+”\n”);}for (OfficeFile officeFile : mOfficeFileList) {builder.append(officeFile.toString()+”\n”);}for (PackageFile packageFile : mPackageFileList) {builder.append(packageFile.toString()+”\n”);}return builder.toString();}}{(String[] args) {BaseFolder folder = new BaseFolder(“cache”, “app cache dir.”);MediaFile mediaFile = new MediaFile(“test.png”, “test picture.”);folder.addMediaFile(mediaFile);mediaFile = new MediaFile(“haha.mp4”, “test video.”);folder.addMediaFile(mediaFile);PackageFile packageFile = new PackageFile(“yanbo.apk”, “an android application.”);folder.addPackageFile(packageFile);BaseFolder childDir = new BaseFolder(“word”, “office dir.”);OfficeFile officeFile = new OfficeFile(“rrrr.doc”, “office doc file.”);childDir.addOfficeFile(officeFile);folder.addBaseFolder(childDir);System.out.println(folder.toString());}}

有了如上实现那么问题来了。。。

世上最累人的事,莫过於虚伪的过日子

设计模式(结构型)之组合模式(Composite Pattern)

相关文章:

你感兴趣的文章:

标签云: