合成模式:有时又叫做部分-整体模式(Part-Whole)。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。

合成模式分为安全式和透明式

安全式合成模式类图:

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。在安全式的合成模式里,构件角色并不是定义出管理子对象的方法,这一定义由树枝构件对象给出。

树叶构件(Leaf)角色:树叶对象是没有下级子对象的对 象,定义出参加组合的原始对象的行为。

树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝对象给出所有的管理子对象的方法,如 add()、remove()、getChild()等。

示例代码:

    class Program
{
static void Main(string[] args)
{
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB"));
root.Add(comp);
root.Add(new Leaf("Leaf C")); Leaf Leaf1 = new Leaf("Leaf D");
root.Add(Leaf1);
root.Remove(Leaf1);
root.Display();
Console.ReadKey();
}
} public abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
} public abstract void Display(int depth);
} public class Composite : Component
{
private ArrayList children = new ArrayList();
public Composite(string name) : base(name) { } public void Add(Component component)
{
children.Add(component);
} public void Remove(Component component)
{
children.Remove(component);
} public override void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
foreach (Component item in children)
{
item.Display(depth + );
}
}
} class Leaf : Component
{
public Leaf(string name) : base(name) { } public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
}
}

运行结果:

透明式合成模式类图:

透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定的接口。

抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象规定一个接口,规范共有的接口及默认行为。

树叶构件(Leaf)角色:代表参加组合的树叶对象,定义 出参加组合的原始对象的行为。树叶类会给出 add()、 remove()以及 getChild()之类的用来管理子类对 对象的方法的平庸实现。

树枝构件(Composite)角色:代表参加组合的有子对 象的对象,定义出这样的对象的行为。

示例代码:

 class CompositePartten2
{
public static void Main(string[] args)
{
Composite root = new Composite("rood");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf b")); Composite comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB")); root.Add(comp); root.Add(new Leaf("Leaf C"));
// Add and remove a leaf
Leaf l = new Leaf("Leaf D");
root.Add(l);
root.Remove(l);
// Recursively display nodes
root.Display(); Console.ReadKey();
}
} abstract class Component
{
protected string name;
public Component(string name)
{
this.name = name;
} public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Display(int c); } class Composite : Component
{
private ArrayList children = new ArrayList(); public Composite(string name) : base(name) { } public override void Add(Component c)
{
children.Add(c);
} public override void Remove(Component c)
{
children.Remove(c);
} public override void Display(int depth)
{
Console.WriteLine(new String('-', depth) + name);
foreach (Component item in children)
{
item.Display(depth + );
}
}
} class Leaf : Component
{
public Leaf(string name) : base(name) { } public override void Add(Component c)
{
Console.WriteLine("Connot add to leaf");
} public override void Remove(Component c)
{
Console.WriteLine("Connot remove from a leaf");
} public override void Display(int c)
{
Console.WriteLine(new String('-', c) + name);
}
}

运行结果:

使用时注意问题:

1、明显的给出父对象的引用。在子对象里面给出父对象的引用,可以很容易的遍历所有父对象。有了这个引用,可以方便的应用责任链模式。

2、在通常的系统里,可以使用享元模式实现构件的共享,但是由于合成模式的对象经常要有对父对象的引用,因此共享不容易实现。

3、有时候系统需要遍历一个树枝结构的子构件很多次,这 时候 可以考虑把遍历子构件的结果暂时存储在父构件里面作为缓存。

4、关于使用什么数据类型来存储子对象的问题,在示意性的 代码中使用了 ArrayList,在实际系统中可以使用其它聚 集或数组等。

5、客户端尽量不要直接调用树叶类中的方法,而是借助其父 类(Component)的多态性完成调用,这样可以增加代 码的复用性

九、 合成(Composite)模式 --结构模式(Structural Pattern)的更多相关文章

  1. 十二、享元(Flyweight)模式--结构模式(Structural Pattern)

    Flyweight在拳击比赛中指最轻量级,即"蝇量级",有些作者翻译为"羽量级".这里使用"享元 模式"更能反映模式的用意. 享元模式以共享 ...

  2. 七、适配器(Adapter)模式--结构模式(Structural Pattern)

    适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作. 类的 Adapter模式的结构: 类适配器类图: 由图中可以看出,Adaptee ...

  3. 十一、外观(Facade)模式--结构模式(Structural Pattern)

    外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式.门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行. 门面模式提供一个高层次 ...

  4. 十、装饰(Decorator)模式 --结构模式(Structural Pattern)

    装饰(Decorator)模式又名包装(Wrapper)模式[GOF95].装饰模式以对客户端透明的方 式扩展对象的功能,是继承关系的一个替代方案. 装饰模式类图: 类图说明: 抽象构件(Compon ...

  5. 八、桥接模式--结构模式(Structural Pattern)

    桥梁模式:将抽象化(Abstraction)与实现化 (Implementation)脱耦,使得二者可以独立地变化. 桥梁模式类图: 抽象化(Abstraction)角色:抽象化给出的定义,并保存 一 ...

  6. 结构型模式概述(Structural Pattern)

    结构型模式可以描述两种不同的东西:类与类的实例.结构型模式可以分为类结构型模式和对象结构型模式. 类结构型模式关心类的组合,可以由多个类组合成一个更大的系统,在类结构型模式中只存在继承关系和实现关系: ...

  7. 设计模式のCompositePattern(组合模式)----结构模式

    一.产生背景 又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 这种模 ...

  8. 合成(composite)模式

    合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述整体与部分的关系.合成模式可以使客户端将单纯元素与复合元素同等看待. 合成模式 合成模式把部分和整 ...

  9. 八、结构模式之组合(Composite)模式

    组合模式属于对象的结构模式,有时又叫做部分-整体模式,组合模式将对象组织到树结构中,可以用来描述整体与部分的联系.其可以使客户端将单纯元素和组合元素同等对待. 当需求中是体现部分与整体层次的结构时,以 ...

随机推荐

  1. C51单片机内存优化

    52本身有256B的数据存储区,如果没在意一些细节,很容易出现RAM超过128就报错的情况.现讲其问题解释如下: 最常见的是以下两种: ① 超过变量128后必须使用compact模式编译,实际的情况是 ...

  2. VS2010下测试程序性能瓶颈

    之前看到Qt的有个BUGreport https://bugreports.qt-project.org/browse/QTBUG-13182 这个BUG是在windows下QFileDialog很慢 ...

  3. ListView中添加ScrollView只显示一两行的问题

    将ListView改为继承NoScrollListView package com.example.brtz.widget; import android.content.Context; impor ...

  4. MFC 消息的分类

    来源:孙鑫 c++ 第6集

  5. What’s the difference between an interface and an abstract class in Java?

    原文 What’s the difference between an interface and an abstract class in Java? It’s best to start answ ...

  6. UITableView系列(1)---Apple缓存池机制

    一.概述 关于UITableView的基本使用, 其实十分简单.但是做App最重要的之一就是细致,技术方面要做到细致, 必须深入了解底层, 才能做出优化让程序跑得更快.那么这一系列文章从我实际项目中获 ...

  7. Java宝典(二)

    --String s = "a" + "b" + "c" + "d"; 一共创建了多少个对象? --对于如下代码: St ...

  8. spftlayer 安装及简单使用

    1,yum -y install python-pip; pip(Python packet index);

  9. hdu 1159 Common Subsequence(LCS最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  10. C# -- 扩展方法的应用(Extension Methods)

    当你有下面这样一个需求的时候,扩展方法就会起到作用:在项目中,类A需要添加功能,我们想到的就是在类A中添加公共方法,这个显而易见肯定可以,但是由于某种原因,你不能修改类A本身的代码,但是确实又需要增加 ...