آموزش دیزاین پترن Builder در کاتلین

آموزش دیزاین پترن Builder در کاتلین
در این پست می‌خوانید:

دیزاین پترن Builder یک دیزاین پترن Creational هست که بهت امکان می ده شئ های پیچیده رو مرحله به مرحله بسازی. این دیزاین پترن بهت امکان می ده تا انواع و نمایش های مختلف یک شئ رو با استفاده از کد ساخت یکسان، تولید کنی.

آموزش دیزاین پترن Builder در کاتلین

دیزاین پترن Builder

دیزاین پترن Builder برای حل چگونه مشکلاتی بوجود آمد؟ یک شئ پیچیده ای رو تصور کن که نیاز به مقدار دهی اولیۀ پر زحمت و گام به گامِ بسیاری از فیلد ها و شئ های تودرتو داره. چنین کد مقدار دهی اولیه معمولا در داخل یک سازندۀ هیولا با پارامتر های بسیاری مدفون می شه. یا حتی بدتر! در سراسر کد Client پراکنده و پریشان هست

دیزاین پترن Builder

ممکنه برای ایجاد یک subclass برای هر پیکربندی ممکن یک شئ، برنامه رو خیلی پیچیده کنی

برای مثال، بیا به نحوۀ ایجاد یک شئ House فکر کنیم. برای ساخت یک خانۀ ساده، نیازه به چهار دیوار و یک کف بسازی، یک در و یک جفت پنجره مناسب نصب کنی و یک سقف بسازی. اما اگر یک خانه ای بزرگتر و روشن تر، با حیاط خلوت و وسایل دیگر (مانند سیستم گرمایش، لوله کشی، سیم کشی برق) بخواهی چی؟

ساده ترین راه حل ارث بری از کلاس House پایه و ایجاد مجموعه ای از Subclass ها برای پوشش تمام ترکیبیات پارامتر ها هست. اما در نهایت با تعداد قابل توجهی از زیر کلاس ها مواجه میشی. هر پارامتر جدید، مانند حالت هشتی به رشد بیشتر این سلسله مراتب نیاز داره(2 به توان n رو که یادت هست واسه اصل ضرب شمارش بدون شمردن؟)

رویکرد دیگری هم وجود داره که شامل تولید مثل Subclass ها نمی شه. تو می تونی یک Constructor غول پیکر مستقیم در کلاس House پایه با تمام پارامتر های ممکن که شئ رو کنترل می کنه ایجاد کنی. در حالی که این راه حل مشکل Subclass ها رو از بین می بره مشکل دیگری ایجاد می کنه.

دیزاین پترن Builder

سازنده با پارامتر های زیاد جنبه های منفی خودش رو داره: همۀ پارامتر ها همیشه مورد نیاز نیستن؛ البته در زبان برنامه نویسی کاتلین سازنده ها منعطف شده اند و استفاده از سازنده ها رو بجای دیزاین پترن Builder می شه در نظر داشت؛ کاتلین خیلی باحاله نه؟

در بیشتر موارد، بیشتر پارامتر ها استفاده نمی شن، و فراخوانی سازنده رو بسیار زشت می کنه. به عنوان مثال تنها کسری از خانه ها دارای استخر شنا هستن، بنابرین پارامتر های مربوط به استخرهای شنا از هر ده بار نه بار بی فایده خواهند بود.

برای حل این مشکل دیزاین پترن Builder پیشنهاد می کنه که کد ساخت شئ رو از کلاس خودش استخراج کنی و آن رو به شئ های جداگانه ای با نام Builder ها منتقل کنی

دیزاین پترن Builder

دیزاین پترن Builder بهت امکان میده گام به گام شئ های پیچیده بسازی. Builder به شئ های دیگر اجازۀ دسترسی به محصول رو در حین ساخت نمی ده.

دیزاین پترن Builder ساخت شئ رو در مجموعه ای از مراحل (buildWalls ، buildDoor و …) ساماندهی می کنه. برای ایجاد یک شئ، یک سریِ متوالی از این مرحله ها رو روی یک شئ Buidler اجرا می کنی. بخش مهم آنه که تو نیازی به فراخوانی همۀ مراحل نداری، تو فقط می تونی آن مرحله هایی رو فراخوانی کنی که برای ایجاد پیکر بندی خاصی از یک شئ ضروری هستن.

زمانی که تو نیاز به ساخت نمایش های مختلف از محصول داری، برخی از مرحله های ساخت و ساز ممکنه به اجرای متفاوتی نیاز داشته باشن. به عنوان مثال، دیوار های یک اتاقک ممکنه از چوب ساخته بشن، اما دیوار های دژ باید از سنگ ساخته بشن.

در این حالت می تونی، چندین کلاس Builder مختلف بسازی که مجموعه مرحله های ساختمانی یکسانی رو اجرا می کنن، اما به شیوه ای متفاوت. سپس می تونی از این Builder ها در فرآیند ساخت و ساز (یعنی مجموعه ای از فراخوان های مرتب شده به مرحله های ساختمان) برای تولید انواع مختلف شئ ها استفاده کنی.

دیزاین پترن Builder

Builder های مختلف یک وظیفه رو به روش های گوناگون انجام می دن

برای مثال Builder ای رو تصور کن که همه چیز رو از چوب و شیشه می سازه، دومی که همه چیز رو از سنگ و آهن می سازه، و سومی که از طلا و الماس استفاده می کنه. با فراخوانی همان مجموعه مرحله ها، از Builder اول یک خانۀ معمولی، از Builder دوم یک دژ کوچک، از سومی یک کاخ دریافت می کنی.

با این حال این تنها در صورتی کار می کنه که آن کد Client ای که مرحله های ساخت رو فراخوانی می کنه، بتونه با استفاده از یک interface مشترک با Builder ها تعامل داشته باشه (Builder به معنای سازنده).

Director

می تونی جلوتر بری و یک سریِ متوالی فراخوان، به مرحله های Builder ای که برای ساختن یک محصول استفاده می کنی؛ در یک کلاس جداگانه به نام Director استخراج کنی. کلاس Director ترتیب اجرای مرحله های ساختن رو مشخص می کنه، در حالی که Builder پیاده سازی آن مرحله ها رو فراهم می کنه.

دیزاین پترن Builder

Director می دونه که کدام مرحله های ساختن رو برای بدست آوردن یک محصول کارآمد اجرا کنه.

داشتن یک کلاس Director در برنامه ات به شدت ضروری نیست. همیشه می تونی مرحله های ساختن رو به ترتیبی خاص مستقیما از کد Client فراخوانی کنی. با این حال کلاس Director ممکنه مکان خوبی برای قرار دادن ساخت و ساز های پرتکرار مختلف باشه تا بتونی ازشان در سراسر برنامۀ خودت دوباره استفاده کنی.

افزون بر این، کلاس Director جزئیات ساخت محصول رو به طور کامل از کد Client پنهان می کنه. Client فقط باید یک Builder رو با یک Director مرتبط کنه، ساخت و ساز رو با Director راه اندازی کنه و نتیجه رو از Builder بگیره.

Do you want to know more about pattern? see this book

ساختار دیزاین پترن Builder

دیزاین پترن Builder

نمودار UML (نمودار UML چیست؟) ساختار دیزاین پترن Builder

Interface اِ Buider : مرحله های ساخت محصول رو که برای انواع Builder ها مشترکه، اعلام می کنه.

Concrete Builder ها : پیاده سازی های مختلفی از مرحله های ساخت و ساز رو ارائه می دن. Concrete Builder ها ممکنه محصولاتی تولید کنن که از interface مشترک پیروی نمی کنن.

Product ها (محصولات) : محصولات، شئ های حاصل هستن. محصولاتی که توسط Builder های مختلف ساخته می شن نیازی نیست از کلاسی یا interface ای ارث بری کرده باشن.

کلاس Director : ترتیب فراخوانی گام ها (مرحله ها) ی ساخت و ساز رو مشخص می کنه، بنابرین می تونی پیکر بندی های خاصی از محصولات رو ایجاد و دوباره استفاده کنی.

Client : Client باید یکی از شئ های Builder ها رو با Director مرتبط کنه. معمولا فقط یکبار از طریق پارامتر های Constructor اِ Director انجام می شه. سپس Director از آن شئ Builder برای ساخت و ساز های بعدی استفاده می کنه.

با این حال، یک رویکرد جایگزین برای زمانی که Client شئ Builder رو به متد تولید کنندۀ Director می فرسته، وجود داره. در این مورد می تونی، هربار که با Director چیزی تولید می کنی، از Builder متفاوتی استفاده کنی.

مثال شبهه کد از دیزاین پترن Builder در کاتلین

این مثال دیزاین پترن Builder نشان میده چگونه می تونی از کد ساخت و ساز Type های مختلف محصولات، مانند اتوموبیل، استفادۀ مجدد کنی و کتابچه راهنمای مربوطه رو برای آنها ایجاد کنی.

دیزاین پترن Builder

مثال ساخت گام به گام خودرو ها و راهنمای کاربر متناسب با آن مدل خودرو ها

می خواهی توی برنامه نویسی اندروید حرفه ای و خفن بشی؟ سرفصل های دورۀ نخبگان اندروید استاد نوری برق از سرت می پرونه!

خودرو یک شئ پیچیده است که به صد ها روش گوناگون میشه آن رو ساخت. بجای آنکه کلاس Car رو با یک Constructor بزرگ پر کنیم، کد مونتاژ خودرو رو در یک کلاس خودروساز (Builder) جداگانه استخراج کردیم. این کلاس مجموعه ای از متد ها برای پیکربندی قسمت های مختلف خودرو داره.

اگر کد Client نیاز به مونتاژ یک مدل خاص و دقیق از خودرو داشته باشه، می تونه مستقیما با Builder کار کنه. از آن سو، مشتری می تونه مونتاژ رو به کلاس Director واگذار کنه، که می دونه چگونه از Builder برای ساخت چندین مدل از محبوب ترین خودرو ها استفاده کنه.

ممکنه یکّه بخوری، اما هر خودرویی به یک دفترچه راهنما نیاز داره(جدا کی می خونتش؟). دفترچه راهنما هرویژگی خودرو رو توصیف می کنه، بنابرین جزئیات موجود در دفترچه راهنما در مدل های گوناگون متفاوت هست. بدین دلیل هست که استفادۀ دوباره از فرآیند ساخت و ساز موجود برای هم خودروی واقعی و هم دفترچه راهنمای مربوطۀ آن خودرو ها منطقی هست.

البته ساختن دفترچه راهنمای ساختن یک خودرو نیست، برای همین ما باید یک کلاس دیگه فراهم کنیم که ویژۀ نوشتن دفترچه راهنمای کاربر باشه. این کلاس همان تابع های ساختن رو مانند برادر خود در زمینۀ خودرو سازی پیاده سازی می کنه، اما بجای ساخت قطعات خودرو، آنها رو توصیف می کنه. با انتقال این سازنده ها به یک شئ Director، می توانیم یک خودرو یا یک دفترچه راهنمای کاربر بسازیم.

بخش آخر واکشی شئ بدست آمده است. یک خودروی فلزی و یک دفترچه راهنمای کاغذی، اگرچه مرتبطن اما دوتا چیز بسیار متفاوتن. ما نمیتونیم متدی رو برای واکشی نتایج در Director بدون جفت کردن Director با کلاس های product اِ concrete ی مشخص قرار دهیم. ازیرا نتیجه ساخت و ساز رو از Builder ای که کار رو انجام داده بدست میاریم.

//پیاده سازی دیزاین پترن بیلدر زمانی معنا داره
//که محصولاتت بسیار پیچیده هستن و نیاز به پیکربندی گسترده دارن
//دو محصول زیر مرتبط هستن، هرچند اینترفیس مشترکی ندارن
class Car{
    //یک خودرو می تونه موقعیت یاب، رایانۀ سفر و تعدادی صندلی
    //داشته باشه. مدل های مختلف خودرو عبارتند از اسپرت، سی یو وی
    //و کابریولت که این مدل ها ویژگی های مختلفی رو نصب یا فعال می کنن
}
class Manual{
    //هر خودرو باید دارای یک دفترچه راهنمای کاربر باشه که مطابق با آن باشه
    //پیکربندی خودرو و تمام ویژگی های آن رو شرح میدهد
}


//اینترفییس بیلدر متد هایی را برای ایجاد بخش های مختلف شئ های محصول
//مشخص می کنه
interface Builder{
    fun reset()
    fun setSeats(i: Int)
    fun setEngine(sportEngine: SportEngine)
    fun setTripComputer(b: Boolean)
    fun setGPS(b: Boolean)
}


class SportEngine {

}

//concrete builder class
//ها از اینترفیس بیلدر پیروی می کنن و پیاده سازی های
//خاصی از مراحل ساخت و ساز رو ارائه میدن
//برنامۀ شما ممکن چندین گونه بیلدر داشته باشه
//که هر یک به طور متفاومتی پیاده سازی شدن
class CarBuilder : Builder{
    private var car : Car? = null

    init {
        reset()
    }

    //شئ درحال ساخت رو پاک می کنه
    override fun reset() {
        car = Car()
    }

    //تمام مراحل تولید با یک نمونه محصول کار می کنن
    override fun setSeats(i: Int) {
        //تعداد صندلی های خودرو رو تنظیم کنین
    }

    override fun setEngine(sportEngine: SportEngine) {
        //یک موتور مشخص رو نصب کنین
    }

    override fun setTripComputer(b: Boolean) {
        //یک رایانۀ سفری نصب کنین
    }

    override fun setGPS(b: Boolean) {
        //یک سیستم موقعیت یابی جهانی نصب کنین
    }

    //concrete builder
    //ها قرار هست متدهای خود رو برای بازیابی ارائه بدن
    //دلیلش هم آنه که انواع مختلف بیلدر ممکنه محصولات کاملا
    //متفاوتی ایجاد کنن که همه از یک اینترفیس پیروی نمی کنن
    //ازیرا چنین متد هایی قابل تعریف در اینترفیس
    //(حداقل نه در یک زبان برنامه نویسی تایپ ایستا)
    //نیستند
    //معمولا پس از بازگردانی نتیجۀ نهایی به کلاینت
    //انتظار می ره یک نمونه بیلدر آماده شروع تولید محصول دیگری باشه
    //به همین دلیله که فراخوانی متد
    //reset
    //در انتهای بدنۀ متد
    //getProduct
    //یک روش معمول هست
    //با این حال این رفتار اجباری نیست و می تونید بیلدر خود رو
    //وادار کنید پیش از حذف نتیجۀ قبلی منتظر یک تماس
    //reset
    //صریح از کد کلاینت باشه

    fun getProduct() : Car?{
        val product = this.car
        reset()
        return product
    }
}

//برخلاف سایر دیزاین پترن های ایجادگری، بیلدر بهتون امکان میده
//محصولاتی بسازید که از اینترفیس مشترک پیروی نمی کنن
class CarManualBuilder : Builder{
    private var manual : Manual? = null

    init {
        reset()
    }

    override fun reset() {
        manual = Manual()
    }

    //ویژگی های صندلی خودرو رو مستند کنین
    override fun setSeats(i: Int) {

    }

    //دستورالعمل های موتور رو بیفزونین
    override fun setEngine(sportEngine: SportEngine) {

    }

    //دستورالعمل های رایانۀ سفر رو بیفزونید
    override fun setTripComputer(b: Boolean) {

    }

    //دستورالعمل های جی پی اس رو بیفزونین
    override fun setGPS(b: Boolean) {

    }

    fun getProduct() : Manual?{
        val product = manual
        reset()
        return manual
        //دستورالعمل ها رو برگردونین و بیلدر رو بازنشانی کنین
    }
}

//director
//تنها مسئول اجرای مراحل ساختمانی در یک توالی خاص است
//هنگام تولید محصولات با توجه به یک سفارش یا پیکربندی خاص سودمند است
//به طور کلی کلاس دایرکتور اختیاری است، زیرا مشتری می تونه بیلدر ها رو
//مستقیما کنترل کنه
class Director{
    //دایرکتور با هر نمونه بیلدر ای که کد کلاینت بهش ارسال می شه کار می کنه
    //بدین ترتیب کد کلاینت ممکنه نوع نهایی محصول تازه مونتاژ شده رو تغییر بده
    //دایرکتور می تونه چندین تنوع محصول رو با استفاده از مراحل ایجادگریِ مشابه بسازه
    fun constructSportsCar(builder : Builder){
        builder.reset()
        builder.setSeats(2)
        builder.setEngine(SportEngine())
        builder.setTripComputer(true)
        builder.setGPS(true)
    }

    fun constructSUV(builder : Builder){

    }
}
//کد کلاینت یک شئ بیلدر می سازه
//آن رو به دایرکتوری می فرسته و سپس مراحل ساخت رو آغاز می کنه
//نتیجۀ نهایی از شئ بیلدر بازیابی می شه
class Application{
    fun makeCar(){
        val director = Director()
        val builderCar : CarBuilder = CarBuilder()
        director.constructSportsCar(builderCar)
        val car = builderCar.getProduct()

        val carManualBuilder = CarManualBuilder()
        director.constructSportsCar(carManualBuilder)

        //محصول نهایی اغلب از شئ بیلدر بازیابی می شه
        //زیرا دایرکتور از بیلدر های
        //concrete
        //و محصول های
        //concrete
        //آگاه نیست و بهشون وابسته نیست
        val manual = carManualBuilder.getProduct()
    }
}

 

قابلیت کاربرد دیزاین پترن Builder

  • از دیزاین پترن Buillder برای خلاص شدن از شر «Telescoping constructor» (یک الگوی طراحی است بدان معنی که تعداد بسیاری سازنده برای کلاس داشته باشیم با پارامتر های متنوع) بهره ببر.

فرض کن سازنده ای با ده پارامتر اختیاری داری. صدا زدن هَمچین جونِوَری رو خوش نمیاد!!! ازیرا از Overload استفاده می کنی و چندین نسخۀ کوتاه تر از سازنده با پارامتر های کمتر ایجاد می کنی. این سازنده ها به سازندۀ اصلی اشاره می کنن و برخی از مقادیر پیش فرض رو به هر پارامترهای حذف شده منتقل می کنن.

class Pizza{
    constructor()
    constructor(size : Int) : this()
    constructor(size : Int,cheese : Boolean) : this(size)
    constructor(size : Int,cheese : Boolean, pepperoni : Boolean) : this(size,cheese)
    //...
}

 دیزاین پترن Builder این امکان رو میده شئ ها رو گام به گام بسازی و فقط از مراحلی استفاده کنی که واقعا به آنها نیاز داری. پس از پیاده سازی دیزاین پترن Builder دیگه نیازی نیست ده ها پارامتر رو در سازندۀ های خود جمع کنی.

  • زمانی که می خواهی کدت بتونه نمایش های مختلفی از یک محصول(برای نمونه خانه های سنگی و چوبی) ایجاد کنه، از دیزاین پترن Builder استفاده کن.

دیزاین پترن Builder رو می شه زمانی اعمال کرد که ساخت نمایش های مختلف محصول شامل مراحل مشابهی باشه که فقط در جزئیات متفاوتن.

اینترفیس بیلدر پایه، تمام مراحل ساخت و ساز ممکن رو تعریف می کنه و concrete builder ها این مرحله ها رو برای ساختن نمایش های خاصی از محصول پیاده سازی می کنن. درضمن کلاس Director دستور های ساخت را رَهنُمایی می کنه.

 

  • از دیزاین پترن Builder برای ساخت «Composite Tree» یا شئ های پیچیده استفاده کن.

دیزاین پترن Builder بهت امکان می ده محصولات رو مرحله به مرحله بسازی. تو میتونی انجام برخی از مراحل رو بدون شکستن محصول نهایی به تعویق بندازی.

تو حتی میتونی مراحل رو بصورت بازگشتی فراخوانی کنی که در مواقعی که نیاز به ساخت tree object داری به کارت میاد. دیزاین پترن Builder هنگام اجرای مراحل ساخت، محصول ناتمام رو در معرض دید قرار نمیده. این کار از دریافت یک نتیجه ناقص توسط Client جلوگیری می کنه.

  1. بی گمان شو که می تونی به روشنی مراحل ساخت و ساز مشترک رو برای ساختن تمام نمایش های محصول موجود تعریف کنی. ورنه نمی تونی به پیاده سازی دیزاین پترن Builder ادامه دهی.
  2. این مرحله ها رو در اینترفیس Builder پایه، تعریف کن.
  3. یک کلاس concrete builder به ازای هر یک از نمایش های محصول ایجاد و مراحل ساخت آنها رو اجرا کن.

پیاده سازی متدی برای واکشی نتیجه ساخت و ساز رو فراموش نکن. دلیل تعریف نکردن این متد در داخل اینترفیس Builder آنه که Builder های مختلف ممکنه محصولاتی بسازن که اینترفیس مشترکی ندارن؛ ازیرا تو نمیدونی که نوع بازگشت برای چنین متدی چه خواهد بود. با این روی اگر با محصولاتی از یک سلسله مراتب سر و کار داری، متد واکشی رو با آسودگی می شه به اینترفیس پایه افزود.

  1. به ایجاد یک کلاس Director بیندیش. ممکنه بشه راه های گوناگون، برای ایجاد یک محصول با استفاده از یک شئ Builder رو، کپسوله سازی کرد.
  2. کد Client هم شئ های Director و هم شئ های Builder رو می سازه. پیش از شروع ساخت و ساز، Client باید یک شئ Builder رو به Director بفرسته. معمولا Client این کار رو فقط یک بار از طریق پارامترهای سازندۀ کلاس Director انجام می ده.

Director در تمام ساخت و ساز های پسین از شئ Builder دریافتی استفاده می کنه. یک رویکرد جایگزین وجود داره که در آن Builder به متد ساخت محصول خاص Director منتقل می شه.

  1. نتیجه ساخت و ساز رو فقط به شرطی از Director می شه بدست آورد که همۀ محصولات از یک اینترفیس استفاده کنن. ورنه، Client باید نتیجه رو از Builder دریافت کنه.

معایب و مزایای دیزاین پترن Builder

مزایای دیزاین پترن Builder :

  • می تونی شئ ها رو گام به گام بسازی، مراحل ساخت رو به تعویق بندازی یا مراحل رو به صورت بازگشتی اجرا کنی.
  • تو می تونی از همون کد ساخت و ساز در هنگام ساختن  نمایش های مختلف محصولات استفادۀ مجدد کنی.
  • با استفاده از دیزاین پترن Builder تو می تونی به اصل Single Responsibility پایبند باشی که یکی از اصل های SOLID هست. می تونی کد ساخت و ساز پیچیده رو از«business logic» محصول جدا کنی.

معایب دیزاین پترن Builder :

  • پیچیدگی کلی کد افزایش می یابه زیرا دیزاین پترن Builder به ایجاد چندین کلاس جدید نیاز داره.

پیوندهای دیزاین پترن Builder با دیگر دیزاین پترن ها

بسیاری از دیزاین پترن ها با استفاده از دیزاین پترن Builder (کمترپیچیده و قابل تنظیم تر از طریق subclass ها) آغاز می شن و به سمت دیزاین پترن Builder یا Prototype و دیزاین پترن Abstract Factory (انعطاف پذیر تر، اما پیچیده تر) تکامل می یابن.

دیزاین پترن Builder بر روی ساختن شئ های پیچیده به صورت گام به گام تمرکز می کنه. Abstract Factory در ایجاد خانواده ای از شئ های مرتبط تخصص داره. Abstract Factory محصول رو فورا بر می گردونه، در حالی که Builder بهت امکان می ده پیش از واکشی محصول، مراحل ساخت و ساز اضافی رو اجرا کنی.

میتونی هنگام ایحاد Composite Tree های پیچیده از دیزاین پترن Builder استفاده کنی، زیرا می تونی مراحل ساخت آن رو طوری برنامه ریزی کنی که به صورت بازگشتی کار کنه.

می تونی دیزاین پترن Builder رو با دیزاین پترن Bridge ترکیب کنی: کلاس Director نقش انتزاع رو بازی می کنه، در حالی که Builder ها به عنوان پیاده سازی عمل می کنن.

دیزاین پترن Builder و دیزاین پترن های Abstract Factory و Prototype همگی می تونن به صورت Singleton پیاده سازی بشن.

پیاده سازی پروژه ای کوچک با استفاده از دیزاین پترن Builder در کاتلین

چنان که یاد شد، دیزاین پترن Builder یکی از دیزاین پترن های Creational هست، که امکان ساخت گام به گام شئ های پیچیده رو فراهم می کنه.

برخلاف سایر دیزاین پترن های Creational، دیزاین پترن Builder نیازی به داشتن یک Interface مشترک از محصولات رو نداره. پس با استفاده از فرآیند ساخت و ساز یکسان می تونیم محصولات مختلف تولید کنیم.

دیزاین پترن Builder بویژه زمانی مفید هست که تو نیاز به ایجاد یک شئ با بسیاری از گزینه های پیکربندی ممکن داری.

مثلا کلاس StringBuilder از این دیزاین پترن پیروی می کنه

تعریف: دیزاین پترن Builder رو می شه در یک کلاس تشخیص داد که دارای یک Creation Method یکتا و چندین متد برای پیکربندی شئ بدست آمده است. متد های سازنده اغلب از زنجیره سازی پیروی می کنن ( برای نمونه : someBuilder.setValueA(1).setValueB(2).create() )

تولید گام به گام خودرو

در این مثال، دیزاین پترن Builder امکان ساخت گام به گام مدل های مختلف خودرو رو فراهم می کنه.

این مثال همپنین نشان میده که دیزاین پترن Builder چطوری محصولاتی از انواع مختلف (دفترچه راهنمای ماشین) رو با استفاده از مراحل یکسان تولید می کنه.

Director ترتیب ساخت و ساز رو کنترل می کنه. می دونه که برای تولید این یا آن مدل خودرو باید از چه فرآیند تولیدی استفاده بکنه. با Builder ها فقط از طریق Interface مشترک آنها کار می کنه. این اجازه می ده تا انواع مختلف Builder ها رو به Director منتقل کنی.

نتیجه نهایی از شئ Builder بازیابی می شه زیرا کار گردان نمیتونه نوع محصول حاصل رو بدونه. فقط شئ Biulder میدونه که دقیقا چه چیزی رو میسازه.

فایل پروژه بعلاوعه دیگر سورس هایی که در پروژه مورد بحث قرار دادیم در انتهای مقاله موجوده که به علت مفصل بودن از آوردن آن در خود مقاله پرهیز کردم. میتونید سورس پروژه کوچک رو بررسی کنین.

دیدگاه‌ها ۰
ارسال دیدگاه جدید