设计模式之笔记--组合模式(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
#引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...
随机推荐
- (二)MySQL学习笔记
1.视图 视图是一系列select语句返回的可视化结果集,是一张虚拟表.更多介绍请查看http://tool.oschina.net/apidocs/apidoc?api=mysql-5.1-zh 视 ...
- Andorid API Package ---> android.app
包名: android.app Added in API level 1 URL:http://developer. ...
- 【题解】CF#280 C-Game on Tree
感觉对期望也一无所知……(:′⌒`)╮(╯﹏╰)╭ 一直在考虑怎么dp,最后看了题解——竟然是这样的???[震惊]但是看了题解之后,觉得确实很有道理…… 我们可以考虑最后答案的组成,可以分开计算不同的 ...
- Android 内核--Context对象
Context(在Android中翻译为场景):一个Activity就是一个Context,一个Service也是一个Context,应用程序中有多少个Activity或者Service,就会有多少个 ...
- 洛谷4245:【模板】任意模数NTT——题解
https://www.luogu.org/problemnew/show/P4245 给两个多项式,求其乘积,每个系数对p取模. 参考: 代码与部分理解参考https://www.luogu.org ...
- C++中的显示类型转换
本文参考了<C++ Primer(中文 第5版)>.<王道程序员求职宝典>以及网上相关博客,结合自己的理解写成.个人水平有限,若有错误欢迎指出. C++中显示转换也成为强制类型 ...
- HDOJ.1070 Milk(贪心)
Milk 点我挑战题目 题意分析 每组测试数据给出一系列牛奶商品,分别是牛奶的品牌,价格,以及体积.在读取数据的时候,体积在200以下的牛奶直接忽略掉.并且每天要喝200ML的牛奶.但是无论牛奶体积有 ...
- java中静态变量与静态方法的继承(转)
总结: 1.静态变量与静态方法说继承并不确切,静态方法与变量是属于类的方法与变量.而子类也属于超类,比如说Manage extends Employee,则Manage也是一个Employee,所以子 ...
- 裸机配置C语言运行环境
C语言程序的执行需要栈的支持.部分soc未初始化栈的情况下调用C语言程序会发生错误. start.S中一共配置了看门狗,svc栈,icache. 在x210中看门狗默认关闭,svc栈默认开启,icah ...
- vijos 1002 简单压缩+DP
描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上 ...