结构型模式 组合模式
Definition
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. |
Participants
The classes and/or objects participating in the Composite pattern are:
|
This structural code demonstrates the Composite pattern which allows the creation of a tree structure in which individual nodes are accessed uniformly whether they are leaf nodes or branch (composite) nodes.
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 );
}
}
This real-world code demonstrates the Composite pattern used in building a graphical tree structure made up of primitive nodes (lines, circles, etc) and composite nodes (groups of drawing elements that make up more complex elements). using System;
using System.Collections;
// "Component"
abstract class DrawingElement
{
// Fields
protected string name;
// Constructors
public DrawingElement( string name )
{
this.name = name;
}
// Methods
abstract public void Add( DrawingElement d );
abstract public void Remove( DrawingElement d );
abstract public void Display( int indent );
}
// "Leaf"
class PrimitiveElement : DrawingElement
{
// Constructors
public PrimitiveElement( string name ) : base( name ) {}
// Methods
public override void Add( DrawingElement c )
{
Console.WriteLine("Cannot Add");
}
public override void Remove( DrawingElement c )
{
Console.WriteLine("Cannot Remove");
}
public override void Display( int indent )
{
Console.WriteLine( new String( '-', indent ) +
" draw a {0}", name );
}
}
// "Composite"
class CompositeElement : DrawingElement
{
// Fields
private ArrayList elements = new ArrayList();
// Constructors
public CompositeElement( string name )
: base( name ) {}
// Methods
public override void Add( DrawingElement d )
{
elements.Add( d );
}
public override void Remove( DrawingElement d )
{
elements.Remove( d );
}
public override void Display( int indent )
{
Console.WriteLine( new String( '-', indent ) +
"+ " + name );
// Display each child element on this node
foreach( DrawingElement c in elements )
c.Display( indent + 2 );
}
}
/// <summary>
/// CompositeApp test
/// </summary>
public class CompositeApp
{
public static void Main( string[] args )
{
// Create a tree structure
CompositeElement root = new
CompositeElement( "Picture" );
root.Add( new PrimitiveElement( "Red Line" ));
root.Add( new PrimitiveElement( "Blue Circle" ));
root.Add( new PrimitiveElement( "Green Box" ));
CompositeElement comp = new
CompositeElement( "Two Circles" );
comp.Add( new PrimitiveElement( "Black Circle" ) );
comp.Add( new PrimitiveElement( "White Circle" ) );
root.Add( comp );
// Add and remove a PrimitiveElement
PrimitiveElement l = new
PrimitiveElement( "Yellow Line" );
root.Add( l );
root.Remove( l );
// Recursively display nodes
root.Display( 1 );
}
}