设计模式之笔记--组合模式(Composite)
组合模式(Composite)
定义
组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式有两种形式:透明方式的组合模式和安全方式的组合模式。
类图

描述
Component:它可以是接口或抽象类,为叶子和容器对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象类中定义了访问及管理它的子类的方法,如增加子对象、删除子对象、获取子对象等;
Leaf:表示叶子节点对象,叶子节点没有子节点,它实现了在抽象类中定义的行为。对于那些访问及管理子类的方法,可以通过异常等方式进行处理,即在叶子对象中实现子类管理和访问方法时需要提供异常处理或错误提示;
Composite:表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象类中定义的行为,包括那些访问及管理子类的方法,在其业务方法中可以递归调用其子节点的业务方法。
应用场景
树枝有多个叶子和子树枝组成,而子树枝又可以包含多个叶子和子树枝;叶子没有子叶子和子树枝。
一、透明方式的组合模式
类图

描述
透明组合模式中,在抽象类Component中声明了所有用于管理成员对象的方法,如Add()、Remove()以及GetChild()等方法,这样做的好处是确保所有的构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以相同地对待所有的对象。
/// <summary>
/// 叶子和树枝的声明接口
/// </summary>
public abstract class Component
{
private string name;
/// <summary>
/// 节点名称
/// </summary>
public string Name
{
get { return name; }
} private int depth;
/// <summary>
/// 节点深度
/// </summary>
public int Depth
{
get { return depth; }
} public Component(string name, int depth)
{
this.name = name;
this.depth = depth;
} #region 管理成员对象的方法
/// <summary>
/// 添加子节点
/// </summary>
/// <param name="component"></param>
public abstract void Add(Component component); /// <summary>
/// 移除子节点
/// </summary>
/// <param name="component"></param>
public abstract void Remove(Component component); /// <summary>
/// 获取子节点
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public abstract Component GetChild(int i);
#endregion /// <summary>
/// 子节点操作
/// </summary>
public abstract void Display(Component component);
} /// <summary>
/// 树枝类
/// </summary>
public class Composite : Component
{
/// <summary>
/// 子节点集合
/// </summary>
private List<Component> children = new List<Component>(); public Composite(string name, int depth)
: base(name, depth)
{ } public override void Add(Component component)
{
this.children.Add(component);
} public override void Remove(Component component)
{
this.children.Remove(component);
} public override Component GetChild(int i)
{
if (i >= && i < this.children.Count)
{
return this.children[i];
}
else
{
return null;
}
} public override void Display(Component component)
{
foreach (Component c in ((Composite)component).children)
{
if (c is Composite)
{
Console.WriteLine(c.Name.PadLeft(c.Depth + c.Name.Length, '-'));
Display(c);
}
else
{
c.Display(c);
}
}
}
} /// <summary>
/// 树叶类
/// </summary>
public class Leaf : Component
{
public Leaf(string name, int depth)
: base(name, depth)
{ } public override void Add(Component component)
{
throw new System.NotImplementedException();
} public override void Remove(Component component)
{
throw new System.NotImplementedException();
} public override Component GetChild(int i)
{
throw new System.NotImplementedException();
} public override void Display(Component component)
{
Console.WriteLine(component.Name.PadLeft(component.Depth + component.Name.Length, '-'));
}
}
二、安全方式的组合模式
类图

描述
安全组合模式中,在抽象类Component中没有声明任何用于管理成员对象的方法,而是在Composite类中声明并实现这些方法。这种做法是安全的,因为根本不向叶子对象提供这些管理成员对象的方法,对于叶子对象,客户端不可能调用到这些方法.
/// <summary>
/// 叶子和树枝的声明接口
/// </summary>
public abstract class Component
{
private string name;
/// <summary>
/// 节点名称
/// </summary>
public string Name
{
get { return name; }
} private int depth;
/// <summary>
/// 节点深度
/// </summary>
public int Depth
{
get { return depth; }
} public Component(string name, int depth)
{
this.name = name;
this.depth = depth;
} /// <summary>
/// 子节点操作
/// </summary>
public abstract void Display(Component component);
} /// <summary>
/// 树枝类
/// </summary>
public class Composite : Component
{
/// <summary>
/// 子节点集合
/// </summary>
private List<Component> children = new List<Component>(); public Composite(string name, int depth)
: base(name, depth)
{ } #region 管理成员对象的方法
/// <summary>
/// 添加子节点
/// </summary>
/// <param name="component"></param>
public void Add(Component component)
{
this.children.Add(component);
} /// <summary>
/// 移除子节点
/// </summary>
/// <param name="component"></param>
public void Remove(Component component)
{
this.children.Remove(component);
} /// <summary>
/// 获取子节点
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
public Component GetChild(int i)
{
if (i >= && i < this.children.Count)
{
return this.children[i];
}
else
{
return null;
}
}
#endregion public override void Display(Component component)
{
foreach (Component c in ((Composite)component).children)
{
if (c is Composite)
{
Console.WriteLine(c.Name.PadLeft(c.Depth + c.Name.Length, '-'));
Display(c);
}
else
{
c.Display(c);
}
}
}
} /// <summary>
/// 树叶类
/// </summary>
public class Leaf : Component
{
public Leaf(string name, int depth)
: base(name, depth)
{ } public override void Display(Component component)
{
Console.WriteLine(component.Name.PadLeft(component.Depth + component.Name.Length, '-'));
}
}
透明和安全方式组合模式的区别在于是否在抽象类Component中定义子对象的管理行为。
设计模式之笔记--组合模式(Composite)的更多相关文章
- 设计模式系列之组合模式(Composite Pattern)——树形结构的处理
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 设计模式 笔记 组合模式 Composite
//---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...
- 设计模式学习心得<组合模式 Composite>
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...
- 学习笔记——组合模式Composite
组合模式,典型的层次结构. 与装饰器类图相似. 区别在于:装饰器模式是为了在接口中增加方法,而组合模式在于层次元素的叠加. ConcreteComponent就是中间结点,可以包含更多的Concret ...
- 《JAVA设计模式》之组合模式(Composite)
在阎宏博士的<JAVA与模式>一书中开头是这样描述合成(Composite)模式的: 合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述 ...
- 设计模式之:组合模式(Composite)
支持原创:http://blog.csdn.net/hguisu/article/details/7530783 设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构 ...
- 设计模式(七)组合模式Composite(结构型)
设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- python 设计模式之组合模式Composite Pattern
#引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...
随机推荐
- openstack中间件message queue 与memcached环境部署
为什么要安装中间件 组件间的通信使用的是REST API 而组件内部之间的通信则是使用的中间件 首先登陆openstack的官网查看官方文档 www.openstack.org 应为在部署一个架构之前 ...
- 使用Visual C ++和Open Folder自定义环境
使用Visual C ++和Open Folder自定义环境 来源 https://blogs.msdn.microsoft.com/vcblog/2016/10/05/bring-your-c-co ...
- java 读写文件乱码问题
这样写,会出现乱码.原因是文件时gbk格式的, BufferedReader br = new BufferedReader(new FileReader(indir)); BufferedWrite ...
- [SOJ #47]集合并卷积
题目大意:给你两个多项式$A,B$,求多项式$C$使得:$$C_n=\sum\limits_{x|y=n}A_xB_y$$题解:$FWT$,他可以解决形如$C_n=\sum\limits_{x\opl ...
- BZOJ3571 & 洛谷3236:[HNOI2014]画框——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3571 https://www.luogu.org/problemnew/show/P3236 小T ...
- BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...
- 20165218 预备作业3 Linux安装及学习
Linux安装及学习 第二节 基本概念及操作 1. 关于图形界面 Linux本身是没有图形界面的,对于初学者来说,这或许是其与Windows系统最直观的差别.Linux所呈现给用户的实际上是一个实现图 ...
- NOIP2016Day1T3换教室(floyd+期望dp)
啊...这个时间写博客,明天还要上学,整个人都不好了... 这是我写的第一道期望题hiahiahia... 题目大意就不说了QWQ 80分儿做法:先floyd,爆搜枚举哪些点取,求出答案,效率O(C( ...
- 背景建模技术(七):预处理(PreProcessor)模块
预处理(PreProcessor)模块是BgsLibrary中一个必选的模块,是真正进入背景建模算法的“预处理”过程,其主要功能包括‘去模糊’.‘获得灰度图’.'应用Canny算子‘等可选模块. 下面 ...
- 【题解】Casting Spells LA 4975 UVa 1470 双倍回文 SDOI 2011 BZOJ 2342 Manacher
首先要吐槽LRJ,书上给的算法标签是“有难度,需要结合其他数据结构”,学完Manacher才发现几乎一裸题 题目的意思是问原串中有多少个wwRwwR这样的子串,其中wR表示w的反串 比较容易看出来,w ...