一、定义

将对象组合成树形结构来表现"整体-部分"层次结构。 组合能让客户以一致的方法处理个别对象以及组合对象。

主要部分可以被一致对待问题.

在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

二、结构

组合模式主要包含三个角色

1.Component(抽象构件) : 为参加组合的对象定义了公共接口和默认行为,声明一个接口用于访问和管理Component子部件。

2.Composite(容器构件):容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

3.Leaf(叶子构件):  代表参加组合的叶子对象(叶子没有后继)。定义组成原始对象的行为。

三、实现

 class Program
{
static void Main(string[] args)
{
MenuComponent menuComponent = new MenuItem("网站");
MenuComponent menuComponent1 = new MenuItem("主页");
MenuComponent menuComponent2 = new MenuItem("产品页");
MenuComponent menuComponent21 = new MenuLeaf("CRM");
MenuComponent menuComponent22 = new MenuLeaf("ERP"); menuComponent.Add(menuComponent1);
menuComponent.Add(menuComponent2);
menuComponent2.Add(menuComponent21);
menuComponent2.Add(menuComponent22);
menuComponent2.Remove(menuComponent21);
}
} public abstract class MenuComponent
{
protected MenuComponent(string name)
{
Name = name;
}
public string Name { get; set; } public abstract void Add(MenuComponent menuComponent);
public abstract void Remove(MenuComponent menuComponent); } public class MenuItem : MenuComponent
{
public MenuItem(string name) : base(name)
{ } public override void Add(MenuComponent menuComponent)
{
Console.WriteLine(Name + "增加: " + menuComponent.Name);
} public override void Remove(MenuComponent menuComponent)
{
Console.WriteLine(Name + "移除: " + menuComponent.Name);
}
}
public class MenuLeaf : MenuComponent
{
public MenuLeaf(string name) : base(name)
{ } public override void Add(MenuComponent menuComponent)
{
throw new Exception("不能增加");
} public override void Remove(MenuComponent menuComponent)
{
throw new Exception("不能移除");
}
}

网站菜单的简单实现

四、适用场景

在以下情况下应该考虑使用组合模式:

  1、 在对象具有部分-整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用这个层次结构也简单。

  2、 系统中需要处理一个树形结构。

  3、 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
  实际应用:  XML解析 、织结构树处理、 件系统设计

五、优缺点

优点: 

  1. 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
  2. 将”客户代码与复杂的对象容器结构“解耦。
  3. 可以更容易地往组合对象中加入新的构件。

缺点:

  1.在增加新构件时很难对容器中的构件类型进行限制。

  2.使设计变得更加抽象、复杂

六、模式扩展

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

  

Head First设计模式之组合模式的更多相关文章

  1. C#设计模式(10)——组合模式(Composite Pattern)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  2. c++设计模式15 --组合模式

    今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...

  3. 乐在其中设计模式(C#) - 组合模式(Composite Pattern)

    原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...

  4. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  5. C#设计模式(10)——组合模式(Composite Pattern)(转)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  6. C#设计模式:组合模式(Composite Pattern)

    一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; ...

  7. 【GOF23设计模式】组合模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_组合模式.树状结构.杀毒软件架构.JUnite底层架构.常见开发场景 package com.test.composite ...

  8. 设计模式:组合模式(Composite)

    定   义:将对象组合树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象使用具有一致性. 结构图: Component类: abstract class Component ...

  9. [设计模式] 8 组合模式 Composite

    DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构.组合使得用户对单个对象和组合对象的使用具有一致性.注意两个字“树形”.这种树形结构在现实生活中随处可见,比如一个集团公司,它有一 ...

  10. 再起航,我的学习笔记之JavaScript设计模式15(组合模式)

    组合模式 组合模式(Composite): 又称部分-整体模式,将对象组合成树形结构以表示"部分整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 如果有一个 ...

随机推荐

  1. 矩阵的奇异值分解(SVD)(理论)

    矩阵的奇异值分解(Singular Value Decomposition,SVD)是数值计算中的精彩之处,在其它数学领域和机器学习领域得到了广泛的应用,如矩阵的广义逆,主分成分析(PCA),自然语言 ...

  2. springmvc 4.3,RequestParamMethodArgumentResolver无法正常解析String参数问题解决

    搭建一个新工程时,想使用最新稳当版的springmvc,所以选择了最新的版本 <dependency> <groupId>org.springframework</gro ...

  3. 《RabbitMQ Tutorial》译文 第 3 章 发布和订阅

    原文来自 RabbitMQ 英文官网的教程(3.Publish and Subscribe),其示例代码采用了 .NET C# 语言. In the previous tutorial we crea ...

  4. Codeforces 482B Interesting Array

    题意:构造一个长度为n的序列,使其满足m个形式如下如下约束:a[l]&a[l+1]&a[l+2]&....&a[r]=q 从Dalao的博客上看到这题,决定去水水.做法 ...

  5. C# Winform 实现Ajax效果自定义按钮

    技术看点 WinForm自定义控件的使用 自定义控件gif动画的播放 需求及效果 又来一波 C# GDI自定义控件show .这个控件已经使用几年了,最近找出来重构一下.原来是没有边框的,那么导致导航 ...

  6. 《重构--改善既有代码的设计》总结or读后感:重构是程序员的本能

    此文写得有点晚,记得去年7月读完的这本书,只是那时没有写文章的意识,也无所谓总结了,现在稍微聊一下吧. 想起写这篇感想,还是前几天看了这么一篇文章 研究发现重构软件并不会改善代码质量 先从一个大家都有 ...

  7. C++教程之autokeyword的使用

    一.autokeyword的前世 从C语言開始,autokeyword就被当作是一个变量的存储类型修饰符,表示自己主动变量(局部变量).它不能被单独使用,否则编译器会给出警告. #include &l ...

  8. 在Flex中推断是否在组件之外单击的技巧

    在Flex中推断是否在组件之外单击的技巧 昨天在做Flex开发的时候.遇到了这样一种操作,之前也遇到过.那时的办法不是非常好,今天又碰上了类似的问题,先看一张图吧! watermark/2/text/ ...

  9. springMVC学习总结(四)springmvc处理json数据类型以及fastjson的使用

    springMVC学习总结(四)springmvc处理json数据类型以及fastjson的使用 主要内容: 这篇文章主要是总结之前使用springmv接收json的时候遇到的问题,下面通过前台发送a ...

  10. Jquery对话框基本配置

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...