时间:2021-05-19
组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
模式图:
适用场景:
举例:
namespace FactoryMethod_DesignPattern{ using System; using System.Collections; abstract class Component { protected string strName; public Component(string name) { strName = name; } abstract public void Add(Component c); public abstract void DumpContents(); // other operations for delete, get, etc. } class Composite : Component { private ArrayList ComponentList = new ArrayList(); public Composite(string s) : base(s) {} override public void Add(Component c) { ComponentList.Add(c); } public override void DumpContents() { // First dump the name of this composite node Console.WriteLine("Node: {0}", strName); // Then loop through children, and get then to dump their contents foreach (Component c in ComponentList) { c.DumpContents(); } } } class Leaf : Component { public Leaf(string s) : base(s) {} override public void Add(Component c) { Console.WriteLine("Cannot add to a leaf"); } public override void DumpContents() { Console.WriteLine("Node: {0}", strName); } } /// <summary> /// Summary description for Client. /// </summary> public class Client { Component SetupTree() { // here we have to create a tree structure, // consisting of composites and leafs. Composite root = new Composite("root-composite"); Composite parentcomposite; Composite composite; Leaf leaf; parentcomposite = root; composite = new Composite("first level - first sibling - composite"); parentcomposite.Add(composite); leaf = new Leaf("first level - second sibling - leaf"); parentcomposite.Add(leaf); parentcomposite = composite; composite = new Composite("second level - first sibling - composite"); parentcomposite.Add(composite); composite = new Composite("second level - second sibling - composite"); parentcomposite.Add(composite); // we will leaf the second level - first sibling empty, and start // populating the second level - second sibling parentcomposite = composite; leaf = new Leaf("third level - first sibling - leaf"); parentcomposite.Add(leaf); leaf = new Leaf("third level - second sibling - leaf"); parentcomposite.Add(leaf); composite = new Composite("third level - third sibling - composite"); parentcomposite.Add(composite); return root; } public static int Main(string[] args) { Component component; Client c = new Client(); component = c.SetupTree(); component.DumpContents(); return 0; } }}
可以看出,Composite类型的对象可以包含其它Component类型的对象。换而言之,Composite类型对象可以含有其它的树枝(Composite)类型或树叶(Leaf)类型的对象。
合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全模式和透明模式。合成模式可以不提供父对象的管理方法,但合成模式必须在合适的地方提供子对象的管理方法(诸如:add、remove、getChild等)。
透明方式
作为第一种选择,在Component里面声明所有的用来管理子类对象的方法,包括add()、remove(),以及getChild()方法。这样做的好处是所有的构件类都有相同的接口。在客户端看来,树叶类对象与合成类对象的区别起码在接口层次上消失了,客户端可以同等同的对待所有的对象。这就是透明形式的合成模式。
这个选择的缺点是不够安全,因为树叶类对象和合成类对象在本质上是有区别的。树叶类对象不可能有下一个层次的对象,因此add()、remove()以及getChild()方法没有意义,是在编译时期不会出错,而只会在运行时期才会出错。
安全方式
第二种选择是在Composite类里面声明所有的用来管理子类对象的方法。这样的做法是安全的做法,因为树叶类型的对象根本就没有管理子类对象的方法,因此,如果客户端对树叶类对象使用这些方法时,程序会在编译时期出错。
这个选择的缺点是不够透明,因为树叶类和合成类将具有不同的接口。
这两个形式各有优缺点,需要根据软件的具体情况做出取舍决定。
安全式的合成模式实现: 只有composite有Add ,remove,delete等方法.
以下示例性代码演示了安全式的合成模式代码:
// Composite pattern -- Structural example using System;using System.Text;using System.Collections;// "Component"abstract class Component{ // Fields protected string name; // Constructors public Component( string name ) { this.name = name; } // Operation public abstract void Display( int depth );}// "Composite"class Composite : Component{ // Fields private ArrayList children = new ArrayList(); // Constructors public Composite( string name ) : base( name ) {} // Methods 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 ); // Display each of the node's children foreach( Component component in children ) component.Display( depth + 2 ); }}// "Leaf"class Leaf : Component{ // Constructors public Leaf( string name ) : base( name ) {} // Methods public override void Display( int depth ) { Console.WriteLine( new String( '-', depth ) + name ); }}/// <summary>/// Client test/// </summary>public class Client{ public static void Main( string[] args ) { // Create a tree structure 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" )); // Add and remove a leaf Leaf l = new Leaf( "Leaf D" ); root.Add( l ); root.Remove( l ); // Recursively display nodes root.Display( 1 ); }}透明式的合成模式实现: 每个里都有add,remove等修改方法.
以下示例性代码演示了安全式的合成模式代码:
实例
再看看一个完整些的例子:
输出:
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
组合模式及其在JDK源码中的运用前言组合和聚合什么是组合模式示例透明组合模式透明组合模式的缺陷安全组合模式组合模式角色组合模式在JDK源码中的体现组合模式应用场
设计模式之单例模式C++实现一、经典实现(非线程安全)classSingleton{public:staticSingleton*getInstance();p
在看《C++设计新思维》的时候,发现在一开始就大篇幅的介绍策略模式(policy),策略模式不属于经典设计模式中的一种,但是其实在我们日常的开发中是必不可少的。
本文实例讲述了JavaScript组合设计模式--改进引入案例。分享给大家供大家参考,具体如下:对于组合设计模式:(1)组合模式中把对象分为两种(组合对象,和叶
php和java,c++一样都是单继承模式。但是像python,是支持多继承(即Mixin模式)。那么如何在php中实现多继承模式?这就需要使用trait。tr