意图

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

适用性

  • 你想表示对象的部分-整体层次结构
  • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

结构

实现

我们实现一个菜单结构,一个菜单可以包含子菜单或者菜单项

定义一个抽象类,菜单和菜单项都继承自这个类

public abstract class MenuComponet
{
public virtual void Add(MenuComponet menuComponet)
{
throw new Exception("不支持该方法");
} public virtual void Remove(MenuComponet menuComponet)
{
throw new Exception("不支持该方法");
} public virtual MenuComponet GetChild(int i)
{
throw new Exception("不支持该方法");
} public virtual void Print()
{
throw new Exception("不支持该方法");
} }

菜单包含一个子节点列表

   public class Menu : MenuComponet
{
List<MenuComponet> _componets = new List<MenuComponet>();
private string _name; public Menu(string name)
{
_name = name;
} public override void Add(MenuComponet menuComponet)
{
_componets.Add(menuComponet);
} public override void Remove(MenuComponet menuComponet)
{
_componets.Remove(menuComponet);
} public override MenuComponet GetChild(int i)
{
return _componets[i];
} public override void Print()
{
Console.WriteLine(_name+":");
foreach (var c in _componets)
{
Console.Write("--");
c.Print();
}
}
}

菜单项

 public class MenuItem : MenuComponet
{
private string _name;
private float _price; public MenuItem(string name, float price)
{
_name = name;
_price = price;
} public override void Print()
{
Console.WriteLine("--"+_name + ": " + _price + "$");
}
}

客户使用

 class Program
{
static void Main(string[] args)
{
MenuComponet allMenus = new Menu("Menu");
MenuComponet breakfast = new Menu("breakfast");
MenuComponet lunch = new Menu("lunch");
MenuComponet dinner = new Menu("dinner"); breakfast.Add(new MenuItem("Milk", 1.5f));
breakfast.Add(new MenuItem("Egg", .5f)); lunch.Add(new MenuItem("Hamburger", 3f));
lunch.Add(new MenuItem("Sausage", 3f));
lunch.Add(new MenuItem("French fries", 2f)); MenuComponet food = new Menu("Food");
MenuComponet drink = new Menu("Drink"); food.Add(new MenuItem("Steak", 6f));
food.Add(new MenuItem("Salad", 3f));
food.Add(new MenuItem("Hamburger", 3f));
drink.Add(new MenuItem("Beer", 1f));
drink.Add(new MenuItem("Wine", 3f));
dinner.Add(food);
dinner.Add(drink); allMenus.Add(breakfast);
allMenus.Add(lunch);
allMenus.Add(dinner);
allMenus.Print(); Console.WriteLine("\n I wanna a beer");
allMenus.GetChild(2).GetChild(1).GetChild(0).Print();
Console.ReadKey();
}
}

运行结果

效果

  • 定义了包含基本对象(不含子节点)和组合对象(含有子节点)的类层次结构
  • 简化客户代码 客户不要关心使用的是组合对象和基本对象,因为使用方法是一致的
  • 容易增加新组件
  • 使设计跟加一般化

设计模式C#实现(十一)——组合模式的更多相关文章

  1. 设计模式(七)组合模式Composite(结构型)

    设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...

  2. Java设计模式(8)组合模式(Composite模式)

    Composite定义:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Composite就应该想到树 ...

  3. 设计模式(十)组合模式(Composite Pattern)

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

  4. js设计模式(六)---组合模式

    组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构.除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性.基本图例 1.组合模式 ...

  5. 设计模式08: Composite 组合模式(结构型模式)

    Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...

  6. 设计模式-(11)组合模式 (swift版)

    一,概念 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...

  7. Delphi 设计模式:《HeadFirst设计模式》Delphi2007代码---组合模式之Menus[转]

     1  2{<HeadFirst设计模式>之组合模式 }  3{ 组合与单项的抽象父类           }  4{ 编译工具:Delphi2007 for win32}  5{ E-M ...

  8. 设计模式(十)——组合模式(HashMap源码解析)

    1 看一个学校院系展示需求 编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院, 一个学院有多个系.如图: 2 传统方案解决学校院系展示 3 传统方案解决 ...

  9. javascript设计模式学习之十——组合模式

    一.组合模式定义及使用场景 组合模式将对象组合成树形结构,用以表示“部分—整体”的层次结构,除了用来表示树形结构之外,组合模式还可以利用对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性. ...

  10. js设计模式(4)---组合模式

    0.前言 今天是建党节,新疆那边又开始了闹腾.作为立志成为码农的我,现在已经从一个大愤青淡化为一个小愤青,对这些国家民生大事不在血气喷发,转而把经历发泄在技术问题上面,因而在扯一篇随笔吧,把无处发泄的 ...

随机推荐

  1. Echars详解

    简介 ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9 /1 ...

  2. Spring注解@Value的用法

    有时候我们在配置文件中使用配置的信息不仅需要在xml文件中使用,还可能在类中使用,这个时候,我们可使用@Value注解了: @Value("${rest.service.url}" ...

  3. Scalaz(18)- Monad: ReaderWriterState-可以是一种简单的编程语言

    说道FP,我们马上会联想到Monad.我们说过Monad的代表函数flatMap可以把两个运算F[A],F[B]连续起来,这样就可以从程序的意义上形成一种串型的流程(workflow).更直白的讲法是 ...

  4. spring 3.x变通实现@Conditional注解的功能

    在某些情况下,我们要根据当前的系统配置决定是否初始化一个bean,也就是条件性加载,比如本地缓存或者分布式缓存,亦或是采用http实现或者socket实现.在spring 4.x中,可以使用新增的@C ...

  5. ajax传参到实体类对应字段

    之前看公司的代码,从页面ajax传参数到接口类,接口类用一个实体接收.我一直以为c#会自动识别,赋值到同名的字段. 我曾和朋友讨论过,双方辩论.朋友认为c#没有这种功能,没有这样高级匹配的机制.而我因 ...

  6. java多线程功力

    一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式.多线程编程可以使程序具有两条或两条以上的并发执行线索. 进程是指一个内存中运行的应用程序,每个进程都有自己 ...

  7. canvas滤镜-刮刮乐

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. [js开源组件开发]html5标签audio的样式更改

    html5标签audio的样式更改 由于html5的流行,现在移动端大多数的需求都可以使用audio来播放音频,但您可能只是需要很简单的播放/停止效果,但不同的浏览器上的audio样式却不尽人意,所以 ...

  9. angular源码分析:injector.js文件分析——angular中的依赖注入式如何实现的(续)

    昨天晚上写完angular源码分析:angular中jqLite的实现--你可以丢掉jQuery了,给今天定了一个题angular源码分析:injector.js文件,以及angular的加载流程,但 ...

  10. C#各种数组直接的数据复制/转换

    之前做Opengl程序,用的的C#的SharpGL这个库,里面有各种奇怪绑定的函数,比如原型为: void glInterleavedArrays(uint format, int stride, v ...