Factory

9 בSeptember 2012

2 תגובות

Factory Pattern

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

מישהו הזכיר Encapsulation ?

תבנית פקטורי מתחלקת לשני מימושים עיקריים  Factory
Method
 למול abstract Factory

נתחיל בראשון שהוא פשוט יותר ומקובל מאוד .

בואו נחשוב על התרחיש הבא.

 

א.     
חנות
חיות שמוכרת חיות מחמד אלקטרונית,

ב.     
בחנות יש
“חיומט” מכונה שבה הלקוחות בוחרים איזו חיה אהובה עליהם.

ג.      
לעת עתה
נסתפק בכלב וחתול.

ד.     
כלב
וחתול בצורתם הלוגית יורשים מ .
animal

ה.     
הלקוח
בוחר חיה וה”חיומט” קורא לבנאי של הקלאס המתאים ופולט מוצר.

  

תרחיש כזה הוא שימוש  קלאסי בfactory method שיודע בזמן ריצה את מי ליצור,

הקליינט לא יודע מה חוזר אליו , הוא רק
מריץ את ה”ייצר לי אובייקט”

כמובן שבמימוש אמיתי למשוואה ייכנסו נגזרות
של קלט משתמש קריאה מקונפיג וכו’  

 

בוא נציג בקוד בסיסי  את מכונת
החיות שלנו (:

namespace FactoryMethod

{

    public
class Factory

    {

        public Animal StartFactory(int AnimalIndex)

        {

 

            Animal beast;

            switch (AnimalIndex)

            {

                case 1:

                    {

                        beast =
new Dog();

                        break;

                    }

 

                case 2:

                    {

                        beast =
new Cat();

                        break;

                    }

 

                default:

                    beast = new Animal();

                    break;

            }

 

            return beast;

        }

    }

 

 

    public
class Animal

    {

        public string Name;

    }

 

    class
Cat : Animal

    {

        public Cat()

        {

            Name = “ketty”;

        }

 

    }

 

    class
Dog : Animal

    {

        public Dog()

        {

            Name = “dogy”;

        }

    }

 

 

 

    class
Program

    {

        static void Main(string[] args)

        {

 

            Console.WriteLine(“=======Welcome
to animal creator===========”
);

            Console.WriteLine(“press
1 for dog or 2 for cat”
);          

            Factory
factor = new Factory();

                 Animal MachineBeast =
factor.StartFactory(int.Parse(Console.ReadLine()));

 

            Console.WriteLine(MachineBeast.Name);

 

        }

    }

}

 

אם הבנו את זה בואו נדבר על החלק השני שזהו הAbstract
Factory

 התרשים, (מתוך ויקיפדיה) מתאר יצירת כפתורים דרך התבנית למערכות שונות

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

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

שאמורים להיווצר או לא בהתאם למה שהלקוח נדרש ()

כדי לפתור בעיה זו נציג פתרון של אספקת חוזה בלי מימוש ספציפי כמו בFactory Method

לכל Interface  כזה יהיו תתי מחלקות שאחראים
על המימוש הרלוונטי וצד הלקוח לא יהיה מודע אליהם ,  הלקוח יעבוד בשיטת שגר ושכח.

המימוש הפשוט יכול להיות באמצעות חוזה משותף שמחזיק פונקציה אחת
שתפקידה הוא להחזיר

את האובייקט הנוכחי בהתאם לתנאי החוזה (inerface)  וכל
אובייקט שאנו רוצים לטפל בו במע’ שלנו

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

בAbstract Factory אנו מקבלים שכבה נוספת שכן אם מדובר בחוזה אפשר לתת לו כמה תתי
חוזים שממשים אותו ובהתאם להפעיל אותם על כל מי שנדרש לפקטורי שלנו.

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

האם אנחנו אמרנו למכונה לאיזה בנק להתקשר? כל שעשינו הוא לנעוץ את
הכרטיס במכונה ומשם ואילך השתחררה פקודת
abstract factory  שיצרה רצף פעולות והודעות
בזמן ריצה בהתאם לכרטיס

ז”א שישנם כמה פונקציות מימוש ל “תתקשר לבנק ותמשוך
כסף” רק הלקוח הפעיל את פונקציית הבסיס (האבסטרקטית) “משיכה” ,

בכדי שלא נתבלבל בין Factory Method  לבין Abstract
Factory
נזכיר רק שעל אותה דוגמא יכולנו לדמות את הFactory Method אם היה רק בנק אחד.. ובהתאם לפעולה נוצר אובייקט..  

 

מימוש נוסף ומתוחכם יוצר יכול להיות באמצעות dynamic שהגיע ב.NET 4

Activator הוא קלאס עם המון יכולות שיודע בזמן ריצה ל”אכול” כל
דבר ולהחזיר לנו אובייקט, ה לא נעשה דרך reflection בד”כ

שימו לב למימוש הבא:

 

public static class
DynamicFactory

{

    public
static object
CreateObject(Type T)

    {

        dynamic d = Activator.CreateInstance(T);

        return d;

    }

}

 

 

public class AnyObject

{

  

}

 

class
Program

{

    static
void Main(string[]
args)

    {

 

        var res = DynamicFactory.CreateObject(typeof(AnyObject));

 

    }

}

 

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

בפוסט הבא נתייחס ל תבנית הbuilder ובמה היא דומה או שונה מהפקטורי.

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

Leave a Reply

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

2 תגובות

  1. tom10 בSeptember 2012 ב 19:20

    האם בילדר חשוב יותר? ומה תפקידו של הקונסטרקטור?

    Reply
  2. tom15 בSeptember 2012 ב 22:26

    בילדר לא חשוב יותר זה שני דברים נפרדים

    Reply