Builder

12 בSeptember 2012

תגיות:
3 תגובות

                                                                                     

 

                                                                                                                                                                                                                                                                                                                        

                                                                            

 תבנית הבילדר היא די פשוטה להבנה ומימוש, הבעיה מתחילה אחרי שפגשנו (בפוסט הקודם) את הפקטורי. 

שם הפוסט אמור היה להיות factory VS builder אבל אני לא מנהל כאן אתר
ארכיאולוגי (עיין ערך חפירות ארכיאולוגיות בגוגל) מטרתי היא להעביר סקירה על
התבניות המצויות ולפשט אותם

בכל זאת אי אפשר בלי התייחסות בסיסית :

כדי להבין מי נגד מי דבר ראשון נחליט שאין לנו קונסטרקטור ב#C.. אוקיי אז ניצור אחד כזה לבד ,

אני מניח שהוא יראה בערך כך על אובייקט שמדמה מגש פיצה.

 

“קלאס פיצה”:

שדות: בצק, רוטב, גבינה , זיתים , תבלינים. (אפשר
להמשיך אבל הרעיון ברור, כל אלמנט הוא שדה של הקלאס פיצה)

בנוסף יכול להיות הבדל בעובי הבצק , בזמן האפייה וכו’

עכשיו צריך לתת אפשרות ליצירת מופעים של פיצה.

ולכן: “פיצה. תכין פיצה , תכניס זיתים… , לא לא זה שרוף לי מדי.. , כמה זה עולה . . . . בלה בלה בלה

זה קצת מפריע לנו שההתעסקות ביצירת אובייקט היא חלק מההגדרה שלו !!

תבנית בילדר נועדה לעשות סדר בבלאגן, ולהחזיר הכל ביחד משהו בסגנון , “תןלי פיצה
חדשה” ולחסוך את ההתעסקות בבנייה בתוך קלאס המודל.

השאלה שצצה מייד היא שלמעשה זה מה שאמורות לעשות תבניות הפקטורי השונות , כמו שהצגנו בפוסט הקודם  ניתן
לקרוא כאן
 ,
 תבנית
פקטורי תכיר את החוזה
Ipizza

ובהתאם לסוג הנדרש תקרא למימוש הפנימי ותחזיר את המופע המבוקש, אם כך מה אני צריך עכשיו תבנית שנקראת builder   ??

התשובה היא פשוטה: שימוש אמיתי בתבנית הבנאי (builder ) תפנה למשתמש ותפעיל
קלאס אחר שיאתחל שדה אחר שדה, תוך אינטראקציה עם המשתמש ולא סתם ליצור מופע בקריאה אחת.

לדוגמא :

קלאס “בונה הפיצה”:

פונקציות: בחר תוספת , בחר עובי בצק , בחר דרגת אפייה וכו’

דוגמת שימוש :

בחר זמן אפייה: תשובה: X , : תודה

בחר תוספת: תשובה: Y,: תודה

בחר תנור מהרשימה: לבנים , ברזל , אפייה במיקרו (רמז, הלכה הפיצה..)
תשובה:
Z , : תודה
 

שמנו לב שישנו הבדל בין הרעיון של קונסטרקטור שלנו ב ,C#  לבין
התבנית המוצגת ,   כי בעת שימוש בתבנית
הבנאי המוצגת אנחנו יורדים לעומק הבנייה ואולי בסוף נבצע קריאה לקונסטרקטור ונגיד
לו
return new object  בהתאם לפרמטרים שאספנו.

בתכנון נכון יותר נרצה להפריד בין התהליך של יצירת האובייקט לבין
הקלאס שמגדיר אותו.

אין שום עניין שהקונסטרקטור של הקלאס יבצע את כל העבודה שתיארנו כאן ,
לכן תבנית ה
builder

כהגדרתה באה להפריד בין האחריות של יצירת אובייקטים (לרוב אובייקטים
מורכבים שתלויים במשתנים שונים) לבין האובייקט עצמו.

ובחזרה לשאלה הפותחת  , עכשיו ניתן לראות בהבדל הבסיסי בין factory  לבין builder שהפקטורי כתבנית ממלאת חלק חשוב
במבנה
encapsulation ומחזירה
אובייקטים מורכבים יותר (דרך
abstract Factory), או פחות (דרך factory Method), שמשותף להם חוזה או קלאס אבא וכו’  לעומת תבנית builder שיותר
חשופה למשתמש
 ומטפלת בבניית האובייקט בצורה ישירה בלי עטיפה אך לעומת זאת גמישה מאוד באפשרויות
הבניין שלה.

הפתיח
הזו הוא תמצית ההסבר על תבנית הבילדר, וזה אומר שהקונסטקטור לא יהיה בתוך קלאס

ואם יהיה לא נפנה אליו ישירות

אלא
במנגנון נפרד שאחראי על ייצור אובייקטים , ונדגים את הרעיון באמצעות דוגמת קוד
מלאה:

namespace Builder_Demo

{

    public enum Extras

    {

        olives,

        onion,

        Homespecial

    }

 

    public enum BakingTime

    {

        regular,

        medium,

        krispy

    }

 

    public enum DoughThickness

    {

        thick,

        thin,

        superThin

    }

 

   public class Pizza

    {

        public Extras extra { get; set; }

        public BakingTime time { get; set; }

        public DoughThickness thickness { get; set; }

        public string CustomerName { get; set; }

        public bool IsReady { get; set; }

    }

 

    public class PizzaBuilder

    {

        public Pizza PizzaObject;

        public PizzaBuilder(string customerName)

        {

            PizzaObject = new Pizza()

            { CustomerName = customerName, IsReady
=
false };

        }

 

        public void buildPizzaExtras(string extra)

        {

            var x = Enum.Parse(typeof(Extras), extra);

            PizzaObject.extra = (Extras)x;

        }

        public void buildPizzaBakingTime(string bakeTime)

        {

            var x = Enum.Parse(typeof(BakingTime), bakeTime);

            PizzaObject.time = (BakingTime)x;

        }

        public void buildPizzaDoughThickness(string doughThickness)


        {

            var x = Enum.Parse(typeof(DoughThickness), doughThickness);

            PizzaObject.thickness = (DoughThickness)x;

        }

        public Pizza CreatePizza()

        {

            PizzaObject.IsReady = true;

            return PizzaObject;

        }

     

 

    }

    class Program

    {

        static void Main(string[] args)

        {

            PizzaBuilder bp = new PizzaBuilder(“barack obama”);

            bp.buildPizzaExtras(“olives”);

            bp.buildPizzaBakingTime(“medium”);

            bp.buildPizzaDoughThickness(“superThin”);

 

            Pizza pizza = bp.CreatePizza();

            Console.WriteLine(pizza.CustomerName + ” youra pizza just ready.. bon appetit !!”);

 

        }

    }

 

}                                                                             
 

 

הוסף תגובה
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *

3 תגובות

  1. יוש15 בSeptember 2012 ב 22:30

    הסבר מעולה. תותח!!

    Reply
  2. jwack15 בSeptember 2012 ב 22:31

    i cant we download the demo code??

    Reply