الگوهای طراحی راه حل های اثبات شده ای برای مشکلات طراحی نرمافزار هستند. آنها به بهبود کیفیت کد، ارتقای قابلیت استفاده مجدد و افزایش قابلیت نگهداری کمک می کنند. ما از آنها برای صرفهجویی در زمان و تولید کد های با کیفیت، توسعهپذیر و انعطافپذیر استفاده میکنیم. در این مطلب قصد داریم الگوی طراحی Builder را معرفی کنیم.
الگوی بیلدر(Builder) یک الگوی ایجادکننده(Creational) است که برای جدا کردن فرآیند ساخت یک شی پیچیده از خود آن کلاس استفاده می شود. به این صورت که برای ایجاد یک شئ، باید از کلاس مجزایی که مسئول ساخت آن شئ است استفاده میکنیم. کلاس بیلدر، میتواند دارای مراحل مختلفی باشد که باید قبل از ساخت شئ، فراخوانی شوند و ویژگی های مختلف شئ را تنظیم کنند.
الگوی بیلدر مخصوصاً هنگام ساخت اشیاء پیچیده که دارای چندین حالت پیکربندی هستند، مانند تنظیم مقادیر پیشفرض، افزودن مقادیر اختیاری و سفارشی کردن شی برای نیازهای خاص، مفید است. با استفاده از این الگو، فرآیند ساخت و ساز را می توان از خود شئ جدا کرد و امکان انعطاف پذیری و نگهداری بیشتر را فراهم کرد.
عناصر اصلی در الگوی بیلدر عبارتند از:
در ادامه مثالی از الگوی بیلدر به زبان سی شارپ آمده است:
public interface IBuilder
{
void SetOptionA(string optionA);
void SetOptionB(string optionB);
void SetOptionC(string optionC);
Product GetResult();
}
public class ConcreteBuilder : IBuilder
{
private Product _product = new Product();
public void SetOptionA(string optionA)
{
_product.OptionA = optionA;
}
public void SetOptionB(string optionB)
{
_product.OptionB = optionB;
}
public void SetOptionC(string optionC)
{
_product.OptionC = optionC;
}
public Product GetResult()
{
return _product;
}
}
public class Director
{
private readonly IBuilder _builder;
public Director(IBuilder builder)
{
_builder = builder;
}
public void Construct()
{
_builder.SetOptionA("Option A");
_builder.SetOptionB("Option B");
_builder.SetOptionC("Option C");
}
}
public class Product
{
public string OptionA { get; set; }
public string OptionB { get; set; }
public string OptionC { get; set; }
}
در این مثال، رابط IBuilder مراحل ساخت شئ را تعریف میکند و کلاس ConcreteBuilder رابط IBuilder را پیادهسازی کرده و هر مرحله را با توجه به نیاز، کامل میکند. کلاس Director فرآیند ساخت و ساز را کنترل می کند و متد های مناسب ConcreteBuilder را برای ساخت شئ نهایی فراخوانی می کند. در نهایت، کلاس Product نمایانگر شی نهایی است که توسط Builder ساخته شده است.
در ادامه مثالی از استفاده این کلاس ها در برنامه آمده است:
var builder = new ConcreteBuilder();
var director = new Director(builder);
director.Construct();
var product = builder.GetResult();
یک مثال واقعی:
یک مثال واقعی از الگوی بیلدر، فرآیند ساخت کامپیوتر و شخصی سازی آن با اجزای سخت افزاری مختلف است.
در ساخت کامپیوتر، قطعات سخت افزاری مختلفی مانند CPU، GPU، RAM، دستگاه های ذخیره سازی و غیره وجود دارد. هر یک از این اجزا دارای تنظیمات و گزینه های مختلفی هستند که می توان آنها را سفارشی کرد، مانند سرعت، ظرفیت و غیره.
برای استفاده از الگوی بیلدر در ساختن کامپیوتر، میتوان یک رابط(Interface) بیلدر تعریف کرد که شامل متدهایی برای افزودن هر قطعه به کامپیوتر، تنظیمات آنها و ایجاد شئ نهایی کامپیوتر است.
public interface IBuilder
{
void AddCPU(string model, int cores, double clockSpeed);
void AddGPU(string model, int vram, double clockSpeed);
void AddRAM(string model, int capacity, int speed);
void AddStorage(string model, int capacity, string type);
void SetPowerSupply(int wattage);
PC GetResult();
}
سپس میتوانیم یک کلاس ConcreteBuilder برای پیادهسازی رابط IBuilder ایجاد کرده و متدهای آن را کامل کنیم.
public class ConcreteBuilder : IBuilder
{
private PC _pc = new PC();
public void AddCPU(string model, int cores, double clockSpeed)
{
_pc.CPU = new CPU(model, cores, clockSpeed);
}
public void AddGPU(string model, int vram, double clockSpeed)
{
_pc.GPU = new GPU(model, vram, clockSpeed);
}
public void AddRAM(string model, int capacity, int speed)
{
_pc.RAM = new RAM(model, capacity, speed);
}
public void AddStorage(string model, int capacity, string type)
{
_pc.Storage = new Storage(model, capacity, type);
}
public void SetPowerSupply(int wattage)
{
_pc.PowerSupply = new PowerSupply(wattage);
}
public PC GetResult()
{
return _pc;
}
}
در نهایت، یک کلاس Director میتواند برای کنترل فرآیند ساخت و فراخوانی متدهای مورد نیاز ConcreteBuilder برای ساختن شیء نهایی PC ایجاد شود.
public class Director
{
private readonly IBuilder _builder;
public Director(IBuilder builder)
{
_builder = builder;
}
public void Construct()
{
_builder.AddCPU("Intel Core i7", 8, 3.6);
_builder.AddGPU("NVIDIA GeForce RTX 3070", 8, 1.5);
_builder.AddRAM("Corsair Vengeance LPX", 16, 3200);
_builder.AddStorage("Samsung 970 EVO", 1, "NVMe");
_builder.SetPowerSupply(650);
}
}
برای استفاده از الگوی ایجاد شده در ساخت کامپیوتر، ابتدا باید یک نمونه از ConcreteBuilder ایجاد کنیم. در مرحله بعد، یک نمونه از Director ایجاد کرده و ConcreteBuilder را به عنوان یک پارامتر ارسال می کنیم. در نهایت، متد Construct را برای ایجاد شیء نهایی PC فراخوانی می کنیم.
var builder = new ConcreteBuilder();
var director = new Director(builder);
director.Construct();
var pc = builder.GetResult();
این الگو در فریمورک های زیادی بکارگرفته شده است که دانستن پشت پرده آن سبب میشود تا از این فریمورک ها به درستی استفاده کنیم.
برای مطالعه سایر الگو های طراحی، میتوانید از لیست زیر استفاده کنید. همچنین یک مخزن کد در گیت هاب که شامل همهی الگو های طراحی میشود، برای شما قرار گرفته است.
من محمدرضا باباخانی هستم، توسعه دهنده نرم افزار. در اینجا تجربیات، نظرات و پیشنهادات خودم رو درباره تکنولوژی مینویسم. امیدوارم مطالبی که مینویسم بدردتون بخوره.
ثبت دیدگاه