
الگوی طراحـــــــــی Composite
الگوی طراحی کامپوزیت یکی از الگوهای ساختاری (Structural Patterns) در طراحی نرمافزار است که از آن برای ایجاد ساختارهای پیچیدهتر از اجتماعی از اشیاء استفاده میشود. این الگو، امکان ترکیب اشیاء به صورت درختی یا سلسلهمراتبی را فراهم میکند به نحوی که اشیاء ترکیب شده به عنوان یک واحد انتخاب و استفاده میشوند.
معمولاً در الگوی طراحی کامپوزیت، از روش ساختار چندسطحی استفاده میشود. این روش به شیوهای سلسلهمراتبی اجازه میدهد تا اشیاء انفرادی و گروههایی از اشیاء را به عنوان یک مجموعه متشکل از اجزاء تلقی کنند. این الگو به برنامهنویسها اجازه میدهد که با استفاده از همان کد، با اجزاء مختلف سازماندهیشده درختی یا سلسلهمراتبی کار کنند.
یک مثال ساده از کاربرد الگوی کامپوزیت در یک ساختار سلسلهمراتبی میتواند در یک درخت بنیادی (Base Tree) با اجزاء گوناگون باشد. هر بخش از این درخت میتواند خودش یک درخت کامپوزیت دیگر باشد که شامل زیربخشها و اجزاء دیگری است. به این ترتیب، ساختارهای پیچیدهتر و بزرگتر از ترکیب اجزاء سادهتر بوجود میآید و کاربردهای مختلفی میتوانند از این الگو بهرهمند شوند.
استفاده از الگوی کامپوزیت مزایایی از قبیل انعطافپذیری و کد قابل استفادهمجدد را فراهم میکند. با استفاده از این الگو، برنامهنویسها میتوانند ساختارهای پیچیدهتر را ایجاد کرده و با اجزاء سادهتر که در درختهای کوچکتر تعریف شدهاند، کار کنند.
لازم به ذکر است که مفاهیم الگوی کامپوزیت در زبانهای برنامهنویسی مختلف به صورت متفاوتی پیادهسازی میشود، اما اصول عمومی این الگو در تمامی زبانها یکسان است. این الگو یکی از الگوهای مهم طراحی نرمافزار است که معمولاً در پروژههایی با ساختارهای پیچیده و تعداد زیادی اجزاء استفاده میشود.
برای درک بهتر این الگو، با یک مثال ملموس و کاربردی در دنیای واقعی آشنا میشویم:
1. Component (اجزا): اینجا کلاس `PurchaseItem` را تعریف میکنیم که ویژگیها و عملیات مشترک مورد خریدها را تعریف میکند.
1public abstract class PurchaseItem
2{
3 protected string name;
4
5 public PurchaseItem(string name)
6 {
7 this.name = name;
8 }
9
10 public abstract decimal GetPrice();
11}
2. Leaf (اجزا ساده): اینجا کلاس `Product` را تعریف میکنیم که از `PurchaseItem` ارثبری کردهاست و محصولات مختلف را پیادهسازی میکند.
1public class Product : PurchaseItem
2{
3 private decimal price;
4
5 public Product(string name, decimal price) : base(name)
6 {
7 this.price = price;
8 }
9
10 public override decimal GetPrice()
11 {
12 return price;
13 }
14}
3. Composite (اجزا ترکیبی): اینجا کلاس `PurchasePackage` را تعریف میکنیم که از `PurchaseItem` ارثبری کردهاست و بستههای خرید را پیادهسازی میکند که میتواند شامل محصولات ساده یا دیگر بستهها باشد.
1public class PurchasePackage : PurchaseItem
2{
3 private List<PurchaseItem> items;
4
5 public PurchasePackage(string name) : base(name)
6 {
7 items = new List<PurchaseItem>();
8 }
9
10 public void AddItem(PurchaseItem item)
11 {
12 items.Add(item);
13 }
14
15 public override decimal GetPrice()
16 {
17 decimal totalPrice = 0;
18 foreach (var item in items)
19 {
20 totalPrice += item.GetPrice();
21 }
22 return totalPrice;
23 }
24}
4. Client (کلاینت): اینجا برنامهای را با توجه به الگوی Composite ایجاد میکنیم و امکان ایجاد خریدهای مختلف و محاسبه هزینه آنها را به کاربر میدهیم.
1public class Program
2{
3 public static void Main()
4 {
5 // ایجاد محصولات ساده
6 PurchaseItem product1 = new Product("Laptop", 2000);
7 PurchaseItem product2 = new Product("Phone", 800);
8 PurchaseItem product3 = new Product("Headphones", 100);
9
10 // ایجاد بستهها
11 PurchaseItem package1 = new PurchasePackage("Electronics Package");
12 PurchaseItem package2 = new PurchasePackage("Gadget Package");
13
14 // اضافه کردن محصولات به بستهها
15 package1.AddItem(product1);
16 package1.AddItem(product2);
17 package2.AddItem(product2);
18 package2.AddItem(product3);
19
20 // ایجاد خریدها
21 PurchaseItem purchase1 = new PurchasePackage("My Purchase");
22 purchase1.AddItem(product1);
23 purchase1.AddItem(package2);
24
25 PurchaseItem purchase2 = new PurchasePackage("Gift Purchase");
26 purchase2.AddItem(package1);
27 purchase2.AddItem(product3);
28
29 // محاسبه هزینه خریدها
30 Console.WriteLine("My Purchase Total Price: " + purchase1.GetPrice());
31 Console.WriteLine("Gift Purchase Total Price: " + purchase2.GetPrice());
32 }
33}
خروجی برنامه به صورت زیر خواهد بود:
1My Purchase Total Price: 2600
2Gift Purchase Total Price: 2900
در این مثال با استفاده از الگوی Composite، توانستیم خریدها را به شکل یک ساختار درختی از محصولات ساده و بستهها مدلسازی کنیم و از هر دو به عنوان یک خرید کامل و محاسبه کل هزینهها استفاده کنیم. این الگو به ما امکان ترکیب اشیاء به شکل ساده و همچنین ترکیب بستهها را میدهد و برنامهنویسی را بسیار آسانتر میکند.