الگوی Builder

الگوی Builder(سازنده-خانه ساز) در دسته الگوهای ایجادی قرار دارد. ساخت یک شی پیچیده را از نمایندگی آن جدا کنید، به طوری که همان فرآیند ساخت می تواند نماینده های مختلفی ایجاد کند.به عبارت دیگر جدا کردن دستورالعمل تولید یک محصول از کسی که محصول را تولید می‌کند و نظارت بر نحوه تولید توسط یک و مدیر به منظور این که بتوان همان محصول را به شکل متفاوتی با قابلیت متفاوت تولید کرد.UML class diagram شركت كنندگان کلاس ها و اشیاء شرکت کننده در این الگو عبارتند از:سازنده-خانه ساز Builder ( در مثال دنیای واقعی کارخانه وسیله نقلیه VehicleBuilder) : یک واسط(Interface) انتزاعی برای ایجاد بخش های یک شیء Product را مشخص می کند.به عبارت دیگر کلاس انتزاعی است که ساختار کلی Builder های تولید کننده ی Product را تعریف می کند و طبق آن مشخص می کند به طور کلی Builder توانایی ساخت چه چیزی را داشته و چه توانمندی هایی برای تولید Product دارد .سازنده-خانه ساز سفتConcreteBuilder (سازنده ماشین ، سازنده موتور سیکلت، سازنده اسکوتر MotorCycleBuilder, CarBuilder, ScooterBuilder) :با پیاده سازی از واسط Builder، بخش هایی از Product را طراحی و مونتاژ می کند.تعریف و نگهداری مسیر( track ) نمایندگی ( representation ) که آن را ایجاد می کند.یک واسط برای بازیابی یک محصول فراهم می کند.به عبارت دیگر یک کلاس سفت است که از Builder مشتق شده است.مدیر-کارگردان Director (فروشگاه Shop): ساخت یک شی را با استفاده از واسط Builder . به عبارت دیگر کلاسی است که یک Builder را دریافت می کند و به او فرمان می‌دهد چگونه Product را تولید کند. محصول Product (وسیله نقلیه Vehicle) :نشان دهنده یک شی پیچیده در حال ساخت است.ConcreteBuilder بازنمایی داخلی محصول را تولید می کند و فرآیندی را که با آن مونتاژ شده است تعریف می کند.شامل کلاس هایی است که اجزای تشکیل دهنده را تعریف می کنند، از جمله واسط ها برای جمع آوری قطعات برای نتیجه نهایی.به عبارت دیگر محصول پیچیده‌ای است که قرار است تولید شود. Builder ها مراحل مختلف ساخت را تعریف کرده و در هر مرحله یک بخش از محصول را می سازند. اما روند ساخت را Director مشخص می کند. ساختار کلی کد الگوی سازنده که در آن اشیاء پیچیده در آن گام به گام ایجاد می شوند. فرایند ساخت و ساز می تواند نمایندگی های مختلف شی ایجاد کند و سطح بالایی از کنترل بر مونتاژ اشیا را فراهم کند. using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Builder.Structural { /// <summary> /// MainApp startup class for Structural /// Builder Design Pattern. /// </summary> public class MainApp { /// <summary> /// Entry point into console application. /// </summary> public static void Main () { // Create director and builders Director director = new Director (); Builder b1 = new ConcreteBuilder1 (); Builder b2 = new ConcreteBuilder2 (); // Construct two products director.Construct (b1); Product p1 = b1.GetResult (); p1.Show (); director.Construct (b2); Product p2 = b2.GetResult (); p2.Show (); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Director' class /// </summary> class Director { // Builder uses a complex series of steps public void Construct (Builder builder) { builder.BuildPartA (); builder.BuildPartB (); } } /// <summary> /// The 'Builder' abstract class /// </summary> abstract class Builder { public abstract void BuildPartA (); public abstract void BuildPartB (); public abstract Product GetResult (); } /// <summary> /// The 'ConcreteBuilder1' class /// </summary> class ConcreteBuilder1 : Builder { private Product _product = new Product (); public override void BuildPartA () { _product.Add ("PartA"); } public override void BuildPartB () { _product.Add ("PartB"); } public override Product GetResult () { return _product; } } /// <summary> /// The 'ConcreteBuilder2' class /// </summary> class ConcreteBuilder2 : Builder { private Product _product = new Product (); public override void BuildPartA () { _product.Add ("PartX"); } public override void BuildPartB () { _product.Add ("PartY"); } public override Product GetResult () { return _product; } } /// <summary> /// The 'Product' class /// </summary> class Product { private List<string> _parts = new List<string> (); public void Add (string part) { _parts.Add (part); } public void Show () { Console.WriteLine ("\nProduct Parts -------"); foreach (string part in _parts) Console.WriteLine (part); } } } OutputProduct Parts-- -- -- -PartAPartBProduct Parts-- -- -- -PartXPartYیا class Director { private Builder builder; public void SetBuilder(Builder builder) { this.builder = builder; } public void Construct() { Console.WriteLine("Directing building of a product ..."); builder.BuildPart1(); builder.BuildPart2(); } } abstract class Builder { protected Product product; public abstract void BuildPart1(); public abstract void BuildPart2(); public virtual Product GetResult() { return product; } public Builder() { product = new Product(); } } class Builder1 : Builder { public override void BuildPart1() { product.Part1 = "Part-A"; Console.WriteLine("Part1 created"); } public override void BuildPart2() { product.Part2 = "Part-B"; Console.WriteLine("Part2 created"); } public override Product GetResult() { product.Name = "Product I"; Console.WriteLine(product.Name + " created"); return base.GetResult(); } } class Builder2 : Builder { public override void BuildPart1() { product.Part1 = "Part-X"; Console.WriteLine("Part1 created"); } public override void BuildPart2() { product.Part2 = "Part-Y"; Console.WriteLine("Part2 created"); } public override Product GetResult() { product.Name = "Product II"; Console.WriteLine(product.Name + " created"); return base.GetResult(); } } class Product { public string Name { get; set; } public string Part1 { get; set; } public string Part2 { get; set; } public void Display() { Console.WriteLine("\nProduct Name: " + this.Name); Console.WriteLine("Part1 : " + this.Part1); Console.WriteLine("Part2 : " + this.Part2); Console.WriteLine(); } } class Client { public static void Main() { Director director = new Director(); var b1 = new Builder1(); var b2 = new Builder2(); director.SetBuilder(b1); director.Construct(); var p1 = b1.GetResult(); p1.Display(); director.SetBuilder(b2); director.Construct(); var p2 = b2.GetResult(); p2.Display(); Console.ReadKey(); } } /* OutputDirecting building of a product ...Part1 createdPart2 createdProduct I createdProduct Name: Product IPart1 : Part-APart2 : Part-BDirecting building of a product ...Part1 createdPart2 createdProduct II createdProduct Name: Product IIPart1 : Part-XPart2 : Part-Y*/مثال دنیای واقعیالگوی سازنده را نشان می دهد که در آن خودروهای مختلف به روش گام به گام مونتاژ می شوند. فروشگاه به وسیله سازندگان خودرو برای ساخت انواع وسایل نقلیه در یک سری از مراحل پیگیری استفاده می کرد. using System; using System.Collections.Generic; namespace DoFactory.GangOfFour.Builder.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Builder Design Pattern. /// </summary> public class MainApp { /// <summary> /// Entry point into console application. /// </summary> public static void Main () { VehicleBuilder builder; // Create shop with vehicle builders Shop shop = new Shop (); // Construct and display vehicles builder = new ScooterBuilder (); shop.Construct (builder); builder.Vehicle.Show (); builder = new CarBuilder (); shop.Construct (builder); builder.Vehicle.Show (); builder = new MotorCycleBuilder (); shop.Construct (builder); builder.Vehicle.Show (); // Wait for user Console.ReadKey (); } } /// <summary> /// The 'Director' class /// </summary> class Shop { // Builder uses a complex series of steps public void Construct (VehicleBuilder vehicleBuilder) { vehicleBuilder.BuildFrame (); vehicleBuilder.BuildEngine (); vehicleBuilder.BuildWheels (); vehicleBuilder.BuildDoors (); } } /// <summary> /// The 'Builder' abstract class /// </summary> abstract class VehicleBuilder { protected Vehicle vehicle; // Gets vehicle instance public Vehicle Vehicle { get { return vehicle; } } // Abstract build methods public abstract void BuildFrame (); public abstract void BuildEngine (); public abstract void BuildWheels (); public abstract void BuildDoors (); } /// <summary> /// The 'ConcreteBuilder1' class /// </summary> class MotorCycleBuilder : VehicleBuilder { public MotorCycleBuilder () { vehicle = new Vehicle ("MotorCycle"); } public override void BuildFrame () { vehicle["frame"] = "MotorCycle Frame"; } public override void BuildEngine () { vehicle["engine"] = "500 cc"; } public override void BuildWheels () { vehicle["wheels"] = "2"; } public override void BuildDoors () { vehicle["doors"] = "0"; } } /// <summary> /// The 'ConcreteBuilder2' class /// </summary> class CarBuilder : VehicleBuilder { public CarBuilder () { vehicle = new Vehicle ("Car"); } public override void BuildFrame () { vehicle["frame"] = "Car Frame"; } public override void BuildEngine () { vehicle["engine"] = "2500 cc"; } public override void BuildWheels () { vehicle["wheels"] = "4"; } public override void BuildDoors () { vehicle["doors"] = "4"; } } /// <summary> /// The 'ConcreteBuilder3' class /// </summary> class ScooterBuilder : VehicleBuilder { public ScooterBuilder () { vehicle = new Vehicle ("Scooter"); } public override void BuildFrame () { vehicle["frame"] = "Scooter Frame"; } public override void BuildEngine () { vehicle["engine"] = "50 cc"; } public override void BuildWheels () { vehicle["wheels"] = "2"; } public override void BuildDoors () { vehicle["doors"] = "0"; } } /// <summary> /// The 'Product' class /// </summary> class Vehicle { private string _vehicleType; private Dictionary<string, string> _parts = new Dictionary<string, string> (); // Constructor public Vehicle (string vehicleType) { this._vehicleType = vehicleType; } // Indexer public string this [string key] { get { return _parts[key]; } set { _parts[key] = value; } } public void Show () { Console.WriteLine ("\n---------------------------"); Console.WriteLine ("Vehicle Type: {0}", _vehicleType); Console.WriteLine (" Frame : {0}", _parts["frame"]); Console.WriteLine (" Engine : {0}", _parts["engine"]); Console.WriteLine (" #Wheels: {0}", _parts["wheels"]); Console.WriteLine (" #Doors : {0}", _parts["doors"]); } } } -- -- -- -- -- -- -- -- -- -- -- -- -- -Vehicle Type : ScooterFrame : Scooter FrameEngine : none# Wheels : 2# Doors : 0 -- -- -- -- -- -- -- -- -- -- -- -- -- - Vehicle Type : CarFrame : Car FrameEngine : 2500 cc# Wheels : 4# Doors : 4 -- -- -- -- -- -- -- -- -- -- -- -- -- - Vehicle Type : MotorCycleFrame : MotorCycle FrameEngine : 500 cc# Wheels : 2# Doors : 0منبع