Head First设计模式——组合模式
最近比较忙,有段时间没有更新设计模式的进度了。今天继续学习组合设计模式。
组合模式的例子我们继续延续上篇《Head First设计模式——迭代器模式》的菜单例子,首先声明下迭代器和组合模式没有什么关系,他们是两个不同模式。只是我们在这个菜单例子的组合模式内部会用到迭代器。
迭代器模式中说到两个餐馆合并然后使用迭代器进行统一处理菜单的打印,但是现在有一个新的需求是原来大菜单中我们希望加入子菜单,比如饭后甜点。那么这个时候对于需求模型来说就是类似下面这样
菜单拥有菜单项,菜单项中可能还拥有子菜单,我们现在要打印菜单。也就是处理每个菜单和菜单项,如何将他们合理的组织起来并统一处理?要解决这个问题,组合模式来实现这一需求。
定义组合模式
组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
这个模式能够创建一个树形结构,如果我们有了一个树形结构的菜单、子菜单和可能还带有菜单项的子菜单,那么任何一个菜单都是一种“组合”。因为它既可以包含其他菜单,也可以包含菜单项。个别对象只是菜单项并未持有其他对象。
利用组合设计菜单
我们需要创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项,换句话说,我们可以针对菜单或菜单项调用相同的方法。
我们画出菜单设计的类图:
MenuComponent:提供接口,让菜单项和菜单共同使用。我们可能会对方法提供一些默认实现,所以我们可以使用抽象类。
MenuItem:继承自MenuComponent,覆盖了它有意义的方法(add,remove不用管)。
Menu:继承自MenuComponent,覆盖对它有意义的方法。
实现组合模式
实现菜单组件
public abstract class MenuComponent
{
public virtual void Add(MenuComponent menuComponent) {
throw new NotSupportedException();
}
public virtual void Remove(MenuComponent menuComponent)
{
throw new NotSupportedException();
}
public virtual MenuComponent GetChild(int i)
{
throw new NotSupportedException();
}
public virtual void GetName()
{
throw new NotSupportedException();
}
public virtual string GetDescription()
{
throw new NotSupportedException();
}
public virtual double GetPrice()
{
throw new NotSupportedException();
}
public virtual bool IsVegetarian()
{
throw new NotSupportedException();
}
public virtual void Print()
{
throw new NotSupportedException();
}
}
实现菜单项
public class MenuItme : MenuComponent
{
string name;
string decription;
bool vegetarian;
double price; public MenuItme(string name, string decription, bool vegetarian, double price)
{
this.name = name;
this.decription = decription;
this.vegetarian = vegetarian;
this.price = price;
} public override string GetName()
{
return name;
}
public override string GetDescription()
{
return decription;
}
public override double GetPrice()
{
return price;
}
public override bool IsVegetarian()
{
return vegetarian;
}
public override void Print()
{
Console.Write(" " + GetName());
if (IsVegetarian())
{
Console.Write("V" + GetName());
}
Console.WriteLine("," + GetPrice());
Console.WriteLine(" --" + GetPrice());
}
}
实现组合菜单
public class Menu:MenuComponent
{
List<MenuComponent> menuComponents = new List<MenuComponent>();
string name;
string description;
public Menu(string name, string description)
{
this.name = name;
this.description = description;
}
public override void Add(MenuComponent menuComponent)
{
menuComponents.Add(menuComponent);
}
public override void Remove(MenuComponent menuComponent)
{
menuComponents.Remove(menuComponent);
}
public override MenuComponent GetChild(int i)
{
return menuComponents[i];
}
public override string GetName()
{
return name;
}
public override string GetDescription()
{
return description;
} public override void Print()
{
Console.Write("\n" + GetName());
Console.WriteLine("," + GetDescription());
Console.WriteLine("---------------------");
foreach (var item in menuComponents)
{
item.Print();
}
}
}
这里菜单打印直接用foreach 循环打印菜单组件,如果遇到另外一个菜单对象则进入子菜单打印。此处就是使用迭代器模式,只不过我偷了个懒直接用了foreach,因为list C#已经实现了迭代器,使用foreach语法即可。《C# Foreach循环本质与枚举器》
测试
MenuComponent breakfastMenu = new Menu("早餐菜单", "早餐供应");
MenuComponent dinnerMenu = new Menu("晚餐菜单", "晚餐供应");
MenuComponent dessertMenu = new Menu("甜点菜单", "晚餐甜点"); MenuComponent allMenus = new Menu("ALL MENUS", "all menus combaind");
//加入菜单
allMenus.Add(breakfastMenu);
allMenus.Add(dinnerMenu);
//加入菜单项
breakfastMenu.Add(new MenuItme("包子", "鲜肉酱肉", false, 2));
dinnerMenu.Add(new MenuItme("牛肉拉面", "拉面配牛肉", false, 15));
dinnerMenu.Add(dessertMenu);
dessertMenu.Add(new MenuItme("梦龙卷", "切件", false, 16)); allMenus.Print();
Head First设计模式——组合模式的更多相关文章
- 16. 星际争霸之php设计模式--组合模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Java设计模式——组合模式
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...
- 【设计模式】Java设计模式 - 组合模式
Java设计模式 - 组合模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- c#设计模式-组合模式
在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象 ...
- [Head First设计模式]生活中学设计模式——组合模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- JAVA 设计模式 组合模式
用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模式. 结构
- javascript设计模式-组合模式
组合模式所要解决的问题: 可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象.可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象. 客户端代码必须区别对象简单对象和 ...
- 设计模式组合模式(Composite)精华
23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例,他们帮助如何创建一个系统独立.这是一个这些对象和陈述的组合. 创建使用继承类的类架构更改实例.的对象类型模型的建 ...
- 设计模式 -- 组合模式 (Composite Pattern)
定义: 对象组合成部分整体结构,单个对象和组合对象具有一致性. 看了下大概结构就是集团总公司和子公司那种层级结构. 角色介绍: Component :抽象根节点:其实相当去总公司,抽象子类共有的方法: ...
- javascript设计模式——组合模式
前面的话 在程序设计中,有一些和“事物是由相似的子事物构成”类似的思想.组合模式就是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的“孙对象”构成的.本文将详细介绍组合模式 宏命令 宏 ...
随机推荐
- HDFS概念名称节点和数据节点-名称节点-文件系统元数据的持久状态
- 亿级消息系统的核心存储:Tablestore发布Timeline 2.0模型
背景 互联网快速发展的今天,社交类应用.消息类功能大行其道,占据了大量网络流量.大至钉钉.微信.微博.知乎,小至各类App的推送通知,消息类功能几乎成为所有应用的标配.根据场景特点,我们可以将消息类场 ...
- ListOfOpenSourcePrograms
ListOfOpenSourcePrograms Contents Desktop Applications Communication Engineering Educational Financi ...
- JS遍历数组
for 如果用var会造成变量声明提前等问题for(var i = 1; i <= arr.length; i++){ console.log(arr[i - 1]);} for(let i = ...
- CSP-J真题分析之中央处理器(CPU)
中央处理器(CPU,central processing unit)作为计算机系统的运算和控制核心,是信息处理.程序运行的最终执行单元.CPU 自产生以来,在逻辑结构.运行效率以及功能外延上取得了巨大 ...
- java什么是方法(Method)?
方法是一组为了实现特定功能的代码块的集合.方法在语法上的功能主要有以下两个: ①:结构化代码 将代码按照功能进行组织,使代码的结构比较清晰,容易阅读和修改,也就是程序的可维护性强. ②:减少代码重复 ...
- HDU 2601
题意:给出一个n求出n=i*j+i+j共有几种组合,i,j>0. 开始挺傻的.没想到化成因式的乘积.- - . 思路:i*j+i+j=(i+1)*(j+1)=n+1 #include<io ...
- 析构函数 p157
析构函数 确保对象的各部分被正确的清除,及做一些用户指定的其他清理工作. 当对象超出它的作用域时,编译器将自动调用析构函数:手动用new在堆上分配的对象空间,需要调用'delete 对象地址'进行手动 ...
- H3C 路由表查找规则(2)
- HDU 1698 Just a Hook (线段树模板题-区间求和)
Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...