组合模式(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)的更多相关文章

  1. 设计模式系列之组合模式(Composite Pattern)——树形结构的处理

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  2. 设计模式 笔记 组合模式 Composite

    //---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...

  3. 设计模式学习心得<组合模式 Composite>

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

  4. 学习笔记——组合模式Composite

    组合模式,典型的层次结构. 与装饰器类图相似. 区别在于:装饰器模式是为了在接口中增加方法,而组合模式在于层次元素的叠加. ConcreteComponent就是中间结点,可以包含更多的Concret ...

  5. 《JAVA设计模式》之组合模式(Composite)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述合成(Composite)模式的: 合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述 ...

  6. 设计模式之:组合模式(Composite)

    支持原创:http://blog.csdn.net/hguisu/article/details/7530783 设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构 ...

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

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

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

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

  9. python 设计模式之组合模式Composite Pattern

    #引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...

随机推荐

  1. Django 2.0 学习(13):Django模板继承和静态文件

    Django模板继承和静态文件 模板继承(extend) Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中 ...

  2. 用css制作空心箭头(上下左右各个方向均有)

    平常在网页中,经常会有空心箭头,除了用图片外,可以用css来实现.基本思路是,用css绘制两个三角形,通过绝对定位让两三角形不完全重叠,例如制作向右的空心箭头,位于前面的三角形border颜色是需要的 ...

  3. [luogu5176] 公约数

    题目描述 求 \[ \sum_{i=1}^n\sum_{j=1}^m\sum_{k=1}^p\gcd(i\cdot j,i\cdot k,j\cdot k)\times \gcd(i,j,k)\tim ...

  4. BZOJ4573:[ZJOI2016]大森林——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=4573 https://www.luogu.org/problemnew/show/P3348#sub ...

  5. BZOJ2453:维护队列——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2453 Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到 ...

  6. Windows相关

    PE WIndows 相关知识 windows 主机防护

  7. [Leetcode] permutations ii 全排列

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  8. UVA.679 Dropping Balls (二叉树 思维题)

    UVA.679 Dropping Balls (二叉树 思维题) 题意分析 给出深度为D的完全二叉树,按照以下规则,求第I个小球下落在那个叶子节点. 1. 默认所有节点的开关均处于关闭状态. 2. 若 ...

  9. React Patterns

    Contents Stateless function JSX spread attributes Destructuring arguments Conditional rendering Chil ...

  10. select2 全拼以及首字母

    转自:https://blog.csdn.net/kanhuadeng/article/details/78475317 具体实现方法为: 首先需要在网上下载select2的源码,并引入到项目中,具体 ...