C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

模式设计c#--结构型--composite

名称 Composite
结构 o_composite.bmp
意图 将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
适用性
  • 你想表示对象的部分-整体层次结构。
  • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

Code Example
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等修改方法.

以下示例性代码演示了安全式的合成模式代码:

// 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; }

  
// Methods
  abstract public void Add(Component c);
  
abstract public void Remove( Component c );
  
abstract public void Display( int depth );
}


// "Composite"
class Composite : Component
{
  
// Fields
  private ArrayList children = new ArrayList();

  
// Constructors
  public Composite( string name ) : base( name ) {}

  
// Methods
  public override void Add( Component component )
  
{ children.Add( component ); }
  
  
public override 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 Add( Component c )
  
{ Console.WriteLine("Cannot add to a leaf"); }

  
public override void Remove( Component c )
  
{ Console.WriteLine("Cannot remove from a leaf"); }

  
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 );
  }

}

posted on 2006-01-03 15:45 梦在天涯 阅读(919) 评论(2)  编辑 收藏 引用 所属分类: Design pattern

评论

# re: 模式设计c#--结构型--composite 2006-05-18 16:00 梦在天涯

用户感觉不到他在处理结合还是一个单体> 这就是此模式的用处所在


  回复  更多评论   

# re: 模式设计c#--结构型--composite 2006-05-18 16:09 梦在天涯

用处: 在c++中用基类指针的数组,在c#中用arraylist都可以 来表示一个带有分支的树结构  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1795865
  • 排名 - 5

最新评论

阅读排行榜