深入理解Java设计模式之组合模式

目录
  • 一、什么是组合模式
    • 动机(Motivation)
    • 意图(Intent)
  • 二、组合模式的结构
    • 结构图说明:
  • 三、组合模式的使用场景
  • 四、组合模式的优缺点
  • 五、组合模式的实现
  • 六、组合模式的.NET下应用

一、什么是组合模式

定义:将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。

动机(Motivation)

客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。

如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?

意图(Intent)

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

组合模式,现在学习就是虚类继承虚类,然后增加虚方法。最终实类继承第二个虚类,重写所有虚方法。

二、组合模式的结构

结构图说明:

(1)Component:组合中的对象声明接口,在适当情况下实现所有类共有的默认行为,声明一个接口用于访问和管理Component的子组件。在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。(可选)

(2)Leaf:在组合中表示叶节点,叶节点没有子节点,定义对象的基本行为。

(3)Composite:定义有子部件的那些部件的行为,存储子部件并在Component接口实现与子部件有关的操作。

(4)Client:通过Component接口操作组合部件的对象。

三、组合模式的使用场景

1.需求重要体现部分与整体的层次结构时

2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

四、组合模式的优缺点

优点

1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。

2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。

缺点

组合模式不容易限制组合中的构件。

五、组合模式的实现

组合模式有两种实现方式,一种是:透明式的组合模式,另外一种是:安全式的组合模式。在这里我就详细说一下何为“透明式”,何为“安全式”。所谓透明式是指“抽象构件角色”定义的接口行为集合包含两个部分,一部分是叶子对象本身所包含的行为(比如Operation),另外一部分是容器对象本身所包含的管理子对象的行为(Add,Remove)。这个抽象构件必须同时包含这两类对象所有的行为,客户端代码才会透明的使用,无论调用容器对象还是叶子对象,接口方法都是一样的,这就是透明,针对客户端代码的透明,但是也有他自己的问题,叶子对象不会包含自己的子对象,为什么要有Add,Remove等类似方法呢,调用叶子对象这样的方法可能(注意:我这里说的是可能,因为有些人会把这些方法实现为空,不做任何动作,当然也不会有异常抛出了,不要抬杠)会抛出异常,这样就不安全了,然后人们就提出了“安全式的组合模式”。所谓安全式是指“抽象构件角色”只定义叶子对象的方法,确切的说这个抽象构件只定义两类对象共有的行为,然后容器对象的方法定义在“树枝构件角色”上,这样叶子对象有叶子对象的方法,容器对象有容器对象的方法,这样责任很明确,当然调用肯定不会抛出异常了。大家可以根据自己的情况自行选择是实现为“透视式”还是“安全式”的,以下我们会针对这两种情况都有实现,具体实现如下:

namespace 透明式的组合模式的实现
{
    /// <summary>
    /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型
    /// </summary>
    public abstract class Folder
    {
        //增加文件夹或文件
        public abstract void Add(Folder folder);
        //删除文件夹或者文件
        public abstract void Remove(Folder folder);
        //打开文件或者文件夹--该操作相当于Component类型的Operation方法
        public abstract void Open();
    }
    /// <summary>
    /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象
    /// </summary>
    public sealed class Word : Folder
    {
        //增加文件夹或文件
        public override void Add(Folder folder)
        {
            throw new Exception("Word文档不具有该功能");
        }
        //删除文件夹或者文件
        public override void Remove(Folder folder)
        {
            throw new Exception("Word文档不具有该功能");
        }
        //打开文件--该操作相当于Component类型的Operation方法
        public override void Open()
        {
            Console.WriteLine("打开Word文档,开始进行编辑");
        }
    }
    /// <summary>
    /// SonFolder类型就是树枝构件,由于我们使用的是“透明式”,所以Add,Remove都是从Folder类型继承下来的
    /// </summary>
    public class SonFolder : Folder
    {
        //增加文件夹或文件
        public override void Add(Folder folder)
        {
            Console.WriteLine("文件或者文件夹已经增加成功");
        }
        //删除文件夹或者文件
        public override void Remove(Folder folder)
        {
            Console.WriteLine("文件或者文件夹已经删除成功");
        }
        //打开文件夹--该操作相当于Component类型的Operation方法
        public override void Open()
        {
            Console.WriteLine("已经打开当前文件夹");
        }
    }
    public class Program
    {
        static void Main()
        {
            Folder myword = new Word();
            myword.Open();//打开文件,处理文件
            myword.Add(new SonFolder());//抛出异常
            myword.Remove(new SonFolder());//抛出异常

            Folder myfolder = new SonFolder();
            myfolder.Open();//打开文件夹
            myfolder.Add(new SonFolder());//成功增加文件或者文件夹
            myfolder.Remove(new SonFolder());//成功删除文件或者文件夹
            Console.Read();
        }
    }
}

以上代码就是“透明式的组合模式”实现,以下代码就是“安全式的组合模式”实现:

namespace 安全式的组合模式的实现
{
    /// <summary>
    /// 该抽象类就是文件夹抽象接口的定义,该类型就相当于是抽象构件Component类型
    /// </summary>
    public abstract class Folder //该类型少了容器对象管理子对象的方法的定义,换了地方,在树枝构件也就是SonFolder类型
    {
        //打开文件或者文件夹--该操作相当于Component类型的Operation方法
        public abstract void Open();
    }
    /// <summary>
    /// 该Word文档类就是叶子构件的定义,该类型就相当于是Leaf类型,不能在包含子对象
    /// </summary>
    public sealed class Word : Folder  //这类型现在很干净
    {
        //打开文件--该操作相当于Component类型的Operation方法
        public override void Open()
        {
            Console.WriteLine("打开Word文档,开始进行编辑");
        }
    }
    /// <summary>
    /// SonFolder类型就是树枝构件,现在由于我们使用的是“安全式”,所以Add,Remove都是从此处开始定义的
    /// </summary>
    public abstract class SonFolder : Folder //这里可以是抽象接口,可以自己根据自己的情况而定
    {
        //增加文件夹或文件
        public abstract void Add(Folder folder);
        //删除文件夹或者文件
        public abstract void Remove(Folder folder);
        //打开文件夹--该操作相当于Component类型的Operation方法
        public override void Open()
        {
            Console.WriteLine("已经打开当前文件夹");
        }
    }
    /// <summary>
    /// NextFolder类型就是树枝构件的实现类
    /// </summary>
    public sealed class NextFolder : SonFolder
    {
        //增加文件夹或文件
        public override void Add(Folder folder)
        {
            Console.WriteLine("文件或者文件夹已经增加成功");
        }
        //删除文件夹或者文件
        public override void Remove(Folder folder)
        {
            Console.WriteLine("文件或者文件夹已经删除成功");
        }
        //打开文件夹--该操作相当于Component类型的Operation方法
        public override void Open()
        {
            Console.WriteLine("已经打开当前文件夹");
        }
    }
    public class Program
    {
        static void Main()
        {
            //这是安全的组合模式
            Folder myword = new Word();
            myword.Open();//打开文件,处理文件

            Folder myfolder = new NextFolder();
            myfolder.Open();//打开文件夹
            //此处要是用增加和删除功能,需要转型的操作,否则不能使用
            ((SonFolder)myfolder).Add(new NextFolder());//成功增加文件或者文件夹
            ((SonFolder)myfolder).Remove(new NextFolder());//成功删除文件或者文件夹
            Console.Read();
        }
    }
}

六、组合模式的.NET下应用

ASP.Net中的Panel对象就是一个Composite对象,而Button对象就是Leaf对象。Button和Panel都继承自System.Web.UI.Control类。它实际上是在Panel里面加了一个Controls属性,然后Controls属性是一个集合属性,它有Add和Remove方法。

在ASP.Net中就是这样,每一个控件都有Controls属性,也就是说每个控件都是一种容器控件(除了LiteralControl)。这种方式把我们对安全性的担忧,统统放到容器(即ASP.Net中的Controls)中去处理。

这个模式在.NET 中最典型的应用就是应用与WinForms和Web的开发中,在.NET类库中,都为这两个平台提供了很多现有的控件,然而System.Windows.Forms.dll中System.Windows.Forms.Control类就应用了组合模式,因为控件包括Label、TextBox等这样的简单控件,这些控件可以理解为叶子对象,同时也包括GroupBox、DataGrid这样复合的控件或者叫容器控件,每个控件都需要调用OnPaint方法来进行控件显示,为了表示这种对象之间整体与部分的层次结构,微软把Control类的实现应用了组合模式(确切地说应用了透明式的组合模式)。

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 分析Java设计模式之组合模式

    目录 一.概述 二. 模式定义 三. 模式结构 四. 模式实现 五. 模式优缺点 5.1.优点 5.2.缺点 六. 模式适用场景 七. 模式总结 一.概述 我们对于这个图片肯定会非常熟悉,这两幅图片我们都可以看做是一个文件结构,对于这样的结构我们称之为树形结构.在数据结构中我们了解到可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作.我们可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象.但是由于容器对象

  • Java设计模式之java组合模式详解

    目录 引言 组合模式介绍 角色 模式结构 示例代码 水果盘 文件浏览 更复杂的组合模式 透明与安全 透明组合模式 安全组合模式 组合模式总结 优点 缺点 适用场景 应用 XML文档解析 文件 HashMap Mybatis SqlNode中的组合模式 参考文章 总结 引言 树形结构不论在生活中或者是开发中都是一种非常常见的结构,一个容器对象(如文件夹)下可以存放多种不同的叶子对象或者容器对象,容器对象与叶子对象之间属性差别可能非常大. 由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中

  • java设计模式-组合模式详解

    目录 组合模式 Demo 代码: 总结 组合模式 组合模式(Composite Pattern)又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 如何解决:树枝和叶子实现统一接口,树枝内部组合该接口. 何时使用:

  • Java设计模式:组合模式

    目录 概述 结构 组合模式案例 分析 总结 在本讲,我们来学习一下结构型模式里面的第六个设计模式,即组合模式. 概述 在学习组合模式之前,我们先来看下面这张图. 对于以上这张图大家应该很熟悉,我们可以将其看作是一个文件系统,其实说到底它就是Windows系统里面的一个目录结构,只不过对于Windows中的文件系统而言,它里面包含有C盘.D盘.E盘等等盘符,而这里我们只是以它里面的某一个盘符里面的目录结构为例来进行了一个描述. 对于这样的结构我们称之为树形结构.为啥叫树形结构呢?你看一下上图中的左

  • 快速理解Java设计模式中的组合模式

    组合模式是一种常见的设计模式(但我感觉有点复杂)也叫合成模式,有时又叫做部分-整体模式,主要是用来描述部分与整体的关系. 个人理解:组合模式就是将部分组装成整体. 定义如下: 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 通用类图如下: 组合模式的包含角色: ● Component 抽象构件角色 定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性. ● Leaf 叶子构件 叶子对象,其下再也没有其他的分支,也就是遍历的最

  • 23种设计模式(10)java组合模式

    23种设计模式第四篇:java组合模式 介绍 组合模式又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解藕. 组合模式可以优化处理递归或分级数据结构.有许多关于分级数据结构的例子,使得组合模式非常有用武之地. 类图 组成部分: Component: 为参加组合的对象声明一个公共接口, 不管是组合还是叶结点. Leaf: 在组合中表示叶子结点对象,叶子结点没有子结点. Composit

  • 深入理解Java设计模式之组合模式

    目录 一.什么是组合模式 动机(Motivation) 意图(Intent) 二.组合模式的结构 结构图说明: 三.组合模式的使用场景 四.组合模式的优缺点 五.组合模式的实现 六.组合模式的.NET下应用 一.什么是组合模式 定义:将对象以树形结构组织起来,以达成"部分-整体"的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. 动机(Motivation) 客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带

  • JAVA设计模式之组合模式原理与用法详解

    本文实例讲述了JAVA设计模式之组合模式.分享给大家供大家参考,具体如下: 组合(整体与部分关系)模式:将不同但是相关的对象组合成树形结构以实现"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. * 模式角色组成: 1.Component对象: 是组合中的对象接口,是所有类共有的接口.是用于统一定义整体中的部分. 2.Leaf对象: 整体中的部分,没有下一级. 3.Composite对象: 用来存储子部件,在Component接口中实现与部分有关操作. 以公司构成

  • Java设计模式之组合模式的示例详解

    目录 定义 原理类图 案例 需求 方案 分析 总结 定义 组合模式,又叫部分整体模式,它创建了对象组的数据结构(将对象组合成树状结构,用来表示部分整体的层级关系)组合模式使得用户对单个对象和组合对象的访问具有一致性 原理类图 Component :这是组合模式中的抽象构件,他里面定义了所有类共有的默认行为,用来访问和管理Component的子部件,Component可以是抽象类,也可以是接口 leaf :在组合模式中表示叶子节点,叶子节点没有子节点了,他是最末端存放数据的结构 Composite

  • Java设计模式之组合模式深入刨析

    目录 1.基本介绍 2.结构 3.组合模式解决的问题 4.组合模式解决学校院系展示 5.组合模式的注意事项和细节 1.基本介绍 1)组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系 2)组合模式依据树形结构来组合对象,用来表示部分以及整体层次 3)这种类型的设计模式属于结构型模式 4)组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象 2.结构 组

  • Java设计模式之组合模式

    本文通过老王和小王探讨书房.书架.各类书的管理问题,引出结构型设计模式家族中的一个重要成员——组合模式,本文会给予两种组合模式的典型代码实现,为了加深理解会在第三部分应用中介绍组合模式在源码中的实际运用,最后总结该设计模式学习后的一些思考. 读者可以拉取完整代码到本地进行学习,实现代码均测试通过后上传到码云,本地源码下载. 一.引出问题 上篇文章中老王给小王买车以后,小王对老王感激涕零,看着老王凌乱的书房,小王提出要帮助老王整理整理他的书架. 小王开始了他的分析.老王平时博览群书,中文.英文.梵

  • java设计模式之组合模式(Composite)

    概述 是一种结构型模式,将对象以树形结构组织起来,以表示"部分 - 整体"的层次结构,使得客户端对单个对象和组合对象的使用具有唯一性. UML类图 上面的类图包含的角色: Component:为参加组合的对象声明一个公共的接口,不管是组合还是叶节点. Leaf:在组合中表示叶子结点对象,叶子结点没有子结点. Composite:表示参加组合的有子对象的对象,并给出树枝构建的行为: 代码示例 import java.util.ArrayList; import java.util.Lis

  • Java设计模式之组合模式(Composite模式)介绍

    Composite定义:将对象以树形结构组织起来,以达成"部分-整体" 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树形结构图.组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行.可以用牵一动百来形容. 所以Composite模式使用到Iterator模式,和Chain of Responsi

  • 深入理解Java设计模式之桥接模式

    目录 二.桥接模式的结构 三.桥接模式的使用场景 四.桥接模式的优缺点 五.装饰,桥接和适配器模式的异同 适配器模式: 桥接模式: 装饰器模式: 六.桥接模式的实现 七.总结 一.什么是桥接模式 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式. 二.桥接模式的结构 在桥接模式结构图中包含如下几个角色: Abstraction(抽象类):用于定义

  • 深入理解Java设计模式之策略模式

    目录 一.什么是策略模式 二.策略模式的结构 三.策略模式的应用场景 四.策略模式的优缺点 六.策略模式的实现 七.策略模式和简单工厂模式的结合 八.策略枚举的实现 九.总结 一.什么是策略模式 策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户.需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数. 策略模式定义和封装了一系列的算法,它们是可以相互替换的,也就是说它们具有

随机推荐