Design Pattern - Composite(C#)
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
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 this pattern are:
- Component (DrawingElement)
- Declares the interface for objects in the composition.
- Implements default behavior for the interface common to all classes, as appropriate.
- Declares an interface for accessing and managing its child components.
- (optional) Defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate.
- Leaf (PrimitiveElement)
- Represents leaf objects in the composition. A leaf has no children.
- Defines behavior for primitive objects in the composition.
- Composite (CompositeElement)
- Defines behavior for components having children.
- Stores child components.
- Implements child-related operations in the Component interface.
- Client (CompositeApp)
- Manipulates objects in the composition through the Component interface.
Sample Code in C#
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.
// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Composite Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; using System.Collections.Generic; /// <summary> /// Startup class for Structural Composite Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create a tree structure var root = new Composite("root"); root.Add(new Leaf("Leaf A")); root.Add(new Leaf("Leaf B")); var 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 var leaf = new Leaf("Leaf D"); root.Add(leaf); root.Remove(leaf); // Recursively display tree root.Display(1); } #endregion } /// <summary> /// The 'Component' abstract class /// </summary> internal abstract class Component { #region Fields /// <summary> /// The name. /// </summary> protected readonly string Name; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Component"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> protected Component(string name) { this.Name = name; } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="c"> /// The c. /// </param> public abstract void Add(Component c); /// <summary> /// The display. /// </summary> /// <param name="depth"> /// The depth. /// </param> public abstract void Display(int depth); /// <summary> /// The remove. /// </summary> /// <param name="c"> /// The c. /// </param> public abstract void Remove(Component c); #endregion } /// <summary> /// The 'Composite' class /// </summary> internal class Composite : Component { #region Fields /// <summary> /// The children. /// </summary> private List<Component> children = new List<Component>(); #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Composite"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> public Composite(string name) : base(name) { } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="component"> /// The component. /// </param> public override void Add(Component component) { this.children.Add(component); } /// <summary> /// The display. /// </summary> /// <param name="depth"> /// The depth. /// </param> public override void Display(int depth) { Console.WriteLine(new string('-', depth) + this.Name); // Recursively display child nodes foreach (Component component in this.children) { component.Display(depth + 2); } } /// <summary> /// The remove. /// </summary> /// <param name="component"> /// The component. /// </param> public override void Remove(Component component) { this.children.Remove(component); } #endregion } /// <summary> /// The 'Leaf' class /// </summary> internal class Leaf : Component { // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Leaf"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> public Leaf(string name) : base(name) { } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="c"> /// The c. /// </param> public override void Add(Component c) { Console.WriteLine("Cannot add to a leaf"); } /// <summary> /// The display. /// </summary> /// <param name="depth"> /// The depth. /// </param> public override void Display(int depth) { Console.WriteLine(new string('-', depth) + this.Name); } /// <summary> /// The remove. /// </summary> /// <param name="c"> /// The c. /// </param> public override void Remove(Component c) { Console.WriteLine("Cannot remove from a leaf"); } #endregion }}// Output:/*-root---Leaf A---Leaf B---Composite X-----Leaf XA-----Leaf XB---Leaf C*/
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).
// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Real-World Composite Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; using System.Collections.Generic; /// <summary> /// Startup class for Real-World Composite Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create a tree structure var root = new CompositeElement("Picture"); root.Add(new PrimitiveElement("Red Line")); root.Add(new PrimitiveElement("Blue Circle")); root.Add(new PrimitiveElement("Green Box")); // Create a branch var 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 var pe = new PrimitiveElement("Yellow Line"); root.Add(pe); root.Remove(pe); // Recursively display nodes root.Display(1); } #endregion } /// <summary> /// The 'Component' tree node /// </summary> internal abstract class DrawingElement { #region Fields /// <summary> /// The name. /// </summary> protected readonly string Name; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="DrawingElement"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> protected DrawingElement(string name) { this.Name = name; } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="d"> /// The d. /// </param> public abstract void Add(DrawingElement d); /// <summary> /// The display. /// </summary> /// <param name="indent"> /// The indent. /// </param> public abstract void Display(int indent); /// <summary> /// The remove. /// </summary> /// <param name="d"> /// The d. /// </param> public abstract void Remove(DrawingElement d); #endregion } /// <summary> /// The 'Leaf' class /// </summary> internal class PrimitiveElement : DrawingElement { // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="PrimitiveElement"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> public PrimitiveElement(string name) : base(name) { } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="c"> /// The c. /// </param> public override void Add(DrawingElement c) { Console.WriteLine("Cannot add to a PrimitiveElement"); } /// <summary> /// The display. /// </summary> /// <param name="indent"> /// The indent. /// </param> public override void Display(int indent) { Console.WriteLine(new string('-', indent) + " " + this.Name); } /// <summary> /// The remove. /// </summary> /// <param name="c"> /// The c. /// </param> public override void Remove(DrawingElement c) { Console.WriteLine("Cannot remove from a PrimitiveElement"); } #endregion } /// <summary> /// The 'Composite' class /// </summary> internal class CompositeElement : DrawingElement { #region Fields /// <summary> /// The elements. /// </summary> private List<DrawingElement> elements = new List<DrawingElement>(); #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="CompositeElement"/> class. /// </summary> /// <param name="name"> /// The name. /// </param> public CompositeElement(string name) : base(name) { } #endregion #region Public Methods and Operators /// <summary> /// The add. /// </summary> /// <param name="d"> /// The d. /// </param> public override void Add(DrawingElement d) { this.elements.Add(d); } /// <summary> /// The display. /// </summary> /// <param name="indent"> /// The indent. /// </param> public override void Display(int indent) { Console.WriteLine(new string('-', indent) + "+ " + this.Name); // Display each child element on this node foreach (DrawingElement d in this.elements) { d.Display(indent + 2); } } /// <summary> /// The remove. /// </summary> /// <param name="d"> /// The d. /// </param> public override void Remove(DrawingElement d) { this.elements.Remove(d); } #endregion }}// Output:/*-+ Picture--- Red Line--- Blue Circle--- Green Box---+ Two Circles----- Black Circle----- White Circle*/