组合模式(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. hdu 1688 Sightseeing (最短路径)

    Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. Javascript 中 == 和 === 区别是什么?

    Javascript 中 == 和 === 区别是什么? 作者:Belleve链接:https://www.zhihu.com/question/31442029/answer/77772323来源: ...

  3. 洛谷 P1969 积木大赛 解题报告

    P1969 积木大赛 题目描述 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为\(n\)的大厦,大厦可以看成由\(n\)块宽度为1的积木组成,第\(i\)块 ...

  4. Mac添加锁屏快捷键

    Mac要想添加锁屏快捷键,必须使用Automator. 1. 打开Automator,创建一个新的服务. 2. 在左侧栏中找到 启动屏幕保护 ,将其拖曳到右侧窗口内,并且修改 服务收到改为" ...

  5. 【博弈论】【P1288】取数游戏II

    传送门 Description 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点 ...

  6. JavaScript中字符串与16进制之间的转换

    一.字符串转换为16进制 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  7. redis中如何对 key 进行分类

    因为redis中的 hash是不支持设置过期时间的,如果我们要 设置过期时间,还要分类存储,可以用下面折中的方法 其实就是我们把 key 定义的有规律一些,通过在key的字符串内部 分类,上图只是因为 ...

  8. HDU2686 费用流 模板

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  9. HDU1711 KMP(模板题)

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. Spring知识点复习

    Spring知识点复习 一.专业术语 侵入式设计 引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类.如:Struts框架 非侵入式设计 引入框架,对现有的类结构没有影响.如:Hiberna ...