الگوی Composite

الگوی Composite در دسته الگوهای ساختاری قرار دارد. ساخت اشیا به ساختارهای درختی برای نشان دادن سلسله مراتب جز به کل ( part-whole hierarchies ) . کامپوزیت Composite به کلاینت ها اجازه می دهد که اشیا و اجزای فردی اشیا را به صورت یکنواخت در نظر بگیرند. - به عبارت دیگر تعریف ساختار اشیایی که واسط مشابهی داشته باشد و بتوانند درختواره سلسله مراتبی ایجاد کند. UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از: مولفه Component (عنصر طراحی DrawingElement) :رابط کاربری برای اشیاء در ترکیب بندی( composition ) را اعلام می کند.رفتار پیش فرض را برای رابط کاربری مشترک( interface common ) برای همه کلاس ها به صورت مناسب پیاده سازی می کند. یک رابط برای دسترسی و مدیریت اجزای فرزند ( interface for accessing and managing its child components ) خود را اعلام می کند.(اختیاری) یک رابط برای دسترسی به والد Component (مولفه) در ساختار بازگشتی را تعریف می کند و در صورتی که مناسب باشد، آن را پیاده سازی می کند.به عبارت دیگر:مولفه-Component کلاس مجردی است که عملیات تمام مولفه های ساختار سلسله مراتبی را تعریف می کند. به متدها و اعضای این کلاس می توانند به سه دسته تقیسم شوند: دستکاری خود مولفهمدیریت مولفه های درون آن ( اضافه و حذف مولفه)فراهم کردن امکانی برای دسترسی مولفه‌های در برگرفته شده به مولفه ی در برگیرنده ( چیزی مانند خصوصیت Parent در درختواره کنترل‌ها)برگ Leaf (عنصر اولیه یا عنصر اصلی PrimitiveElement) :اشیاء برگ در ترکیب بندی را نشان می دهد. برگ هیچ فرزندی ندارد.رفتار برای اشیاء اولیه/اصلی در ترکیب بندی را تعریف می کند.به عبارت دیگر: نمونه ی کلاس یکی از مولفه های تکی (برگ ها) چه چیزی درون آن ها قرار نمی گیرد .مرکب/مخلوط Composite ( عنصر مرکب/مخلوط CompositeElement) : رفتارهای اجزاء(components) دارای فرزند را تعریف می کند. ذخیره اجزای فرزند (stores child components).عملیات مرتبط با فرزند(child-related) را در رابط کامپوننت(Component interface) پیاده سازی می کند.به عبارت دیگر: نمونه ی کلاس یکی از مولفه های گروهی(مولفه هایی که می‌توانند سایر مولفه ها را درون خود حمل کنند) کلاینت Client (اپ مرکب CompositeApp)دستکاری اشیاء در ترکیب بندی از طریق رابط مولفه ( Component interface ).ساختار کلی کداین کد ساختاری الگوی کامپوزیتی را نشان می دهد که به ایجاد یک ساختار درختی می انجامد که در آن گره های فرد به طور یکنواخت دسترسی پیدا می کنند که آیا آنها گره های برگ یا گره های کامپوزیت هستند. using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Composite.Structural { /// <summary> /// MainApp startup class for Structural /// Composite Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // 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 leaf = new Leaf ("Leaf D"); root.Add (leaf); root.Remove (leaf); // Recursively display tree root.Display (1); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Component' abstract class /// </summary> abstract class Component { protected string name; // Constructor public Component (string name) { this.name = name; } public abstract void Add (Component c); public abstract void Remove (Component c); public abstract void Display (int depth); } /// <summary> /// The 'Composite' class /// </summary> class Composite : Component { private List<Component> _children = new List<Component> (); // Constructor public Composite (string name) : base (name) { } 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); // Recursively display child nodes foreach (Component component in _children) { component.Display (depth + 2); } } } /// <summary> /// The 'Leaf' class /// </summary> class Leaf : Component { // Constructor public Leaf (string name) : base (name) { } 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); } } } Output - root -- - Leaf A -- - Leaf B -- - Composite X -- -- - Leaf XA -- -- - Leaf XB -- - Leaf Cیا بدون درنظر گرفتن کلاینتpublic 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 depth); } class Composite : Component { private List<Component> components = new List<Component>(); public Composite(string name): base(name) { } public Composite(string name, Component[] components): base(name) { foreach (Component component in components) { Add(component); } } public override void Add(Component component) { components.Add(component); } public override void Remove(Component component) { components.Remove(component); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + name); foreach (Component component in components) { component.Display(depth + 2); } } } class Leaf : Component { public Leaf(string name): base(name) { } 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); } } public class Test { public static void Main() { Component c = new Composite("root", new Component[] { new Leaf("Leaf A"), new Leaf("Leaf B"), new Composite("Composite X", new Component[] { new Leaf("Leaf XA"), new Leaf("Leaf XB") } ), new Leaf("Leaf C") } ); c.Display(1); Console.ReadKey(); } } /* Output-root---Leaf A---Leaf B---Composite X-----Leaf XA-----Leaf XB---Leaf C*/کد در دنیای واقعی این کد نشان دهنده الگوی کامپوزیتی است که در ساخت یک ساختار درختی گرافیکی ساخته شده از گره های اولیه (خطوط، حلقه ها، و غیره) و گره های کامپوزیت (گروه های عناصر رسم که عناصر پیچیده تر را تشکیل می دهند) را نشان می دهد. using System.Collections.Generic; using System; namespace DoFactory.GangOfFour.Composite.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Composite Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main () { // 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")); // Create a branch 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 pe = new PrimitiveElement ("Yellow Line"); root.Add (pe); root.Remove (pe); // Recursively display nodes root.Display (1); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Component' Treenode /// </summary> abstract class DrawingElement { protected string _name; // Constructor public DrawingElement (string name) { this._name = name; } public abstract void Add (DrawingElement d); public abstract void Remove (DrawingElement d); public abstract void Display (int indent); } /// <summary> /// The 'Leaf' class /// </summary> class PrimitiveElement : DrawingElement { // Constructor public PrimitiveElement (string name) : base (name) { } public override void Add (DrawingElement c) { Console.WriteLine ( "Cannot add to a PrimitiveElement"); } public override void Remove (DrawingElement c) { Console.WriteLine ( "Cannot remove from a PrimitiveElement"); } public override void Display (int indent) { Console.WriteLine ( new String ('-', indent) + " " + _name); } } /// <summary> /// The 'Composite' class /// </summary> class CompositeElement : DrawingElement { private List<DrawingElement> elements = new List<DrawingElement> (); // Constructor public CompositeElement (string name) : base (name) { } 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 d in elements) { d.Display (indent + 2); } } } } Output - +Picture -- - Red Line -- - Blue Circle -- - Green Box -- - +Two Circles -- -- - Black Circle -- -- - White Circleمنبع