תבנית עיצוב factory

הסבר מעשי, באמצעות דוגמאות ב-PHP על תבנית העיצוב Factory ואיך ולמה צריך להשתמש בה.

במאמר קודם דיברתי על MVC וקיבלתי לא מעט תגובות טובות, לפיכך החלטתי להסביר מעט גם על Factory שלמרות שהיא פחות הוליסטית מ-MVC, שווה להכיר אותה כדי לפחות לא להיות מובכים בפעם הבאה שתגיעו לאיזה כנס ומישהו יעלה לבמה וידבר על זה.
לגבי אלו שלמדו מדעי המחשב וכבר מכירים את Factory – המאמר הזה יהיה מאד טריוויאלי עבורכם. אולי למעט הדוגמה ב-PHP.

אז מה זה Factory? אם נפתח ויקיפדיה בערך של תבנית עיצוב: factory נגלה שמדובר בתבנית עיצוב ב-OOP שמאפשרת לנו לבנות אובייקטים בלי להכיר את המחלקות שלהם.

טוב, זו ההגדרה הרשמית, מה זה בת'כלס אומר? בואו ונסתכל למשל על קוד שמופיע בדוקומנטציה הרשמית של PHP:


class Example
{
    // The parameterized factory method
    public static function factory($type)
    {
        if (include_once 'Drivers/' . $type . '.php') {
            $classname = 'Driver_' . $type;
            return new $classname;
        } else {
            throw new Exception('Driver not found');
        }
    }
}

מדובר ב-Class חביב ופשוט למדי. יש לו מתודה אחת פומבית (כך שאפשר לקרוא לה מחוץ ל-Class) וסטטית (כך שאי אפשר לשנות אותה באמצעות הורשה) שמה שהיא עושה זה לבדוק אם יש דרייברים מסוג מסוים בספרית Drivers כאשר שם הדרייבר אמור להנתן באמצעות המשתנה type. במידה ויש דרייבר, היא יוצרת אובייקט ומחזירה אותו.
במידה ואין – היא מחזירה Exception.

איך מפעילים את ה-Class הזה? יש לנו שתי דוגמאות: אחת עם דרייבר של MySQL והשניה עם SQLite:


// Load a MySQL Driver
$mysql = Example::factory('MySQL');

// Load an SQLite Driver
$sqlite = Example::factory('SQLite');

עד כאן הקוד פשוט להבנה – אז מה הקטע של ה-Factory? שימו לב שאני יוצר כאן אובייקטים בצורה מובנית בלי להתעסק עם התהליך של היצירה שלהם. כל מה שאני צריך לעשות זה לספק את השם של הדרייבר שלי – כמו למשל MySQL. ברגע שסיפקתי את השם – אין יותר ביג'אראס, לא צריך לעשות include לקובץ שמכיל את התיקיה שבה יש את ה-class, לא צריך לקרוא לאופרטור new, אני מקבל בחזרה רפרנס לאובייקט שלי וזה הכל!
יתרה מכך, במידה ואין את הדרייבר מסיבה כלשהי, אני מקבל שגיאה שקל לי לעבוד איתה ולעשות פולבק במידת הצורך.

למה זה טוב? זה טוב במיוחד אם יש לנו פעולות זהות שאנו קוראים להם במהלך הקוד ואנו לא רוצים להתחיל בכל פעם להגדיר את ה-Class ואת הפרמטרים השונים שלו. כך אנחנו מרכזים בעצם את יצירת האובייקטים הרלוונטיים במקום אחד וקוראים להם בכל פעם לפי הצורך עם הפרמטרים המתאימים. כך למשל הקוד הקודם יכול להתאים לתוכנה שמתחברת לכמה מסדי נתונים שונים בהתאם לסוג הדף או לסוג הקריאה.

אולי זה יהיה מובן באמצעות דוגמה מוחשית יותר. בואו ונניח שיש לי אפליקציה שמציגה מוצרים שונים. לכל מוצר יש Class משלו – למשל Computer או Tablet. יש באפליקציה שלנו מספר דפים שכל אחד מהם אני צריך לבצע קריאה ל-Class המתאים. בשיטה הסטנדרטית, אם למשל יש לי tablet.php אני אצטרך לקרוא ל-class בשם tablet וכך הלאה. ברור לכם שאם יש לי דף קטלוגי אני צריך לבצע קריאות ל-Classים השונים בהתאם למוצרים שיש בדף. אם אני עובד בתבנית עיצוב מסוג factory, אני לא צריך לשבור את הראש ולבצע קריאות נפרדות ל-class כל פעם אלא פשוט לקרוא רק ל-factory שתבצע את כל העבודה בהתאם למה שאני מעביר לה.

בואו ונסתכל על הקוד שוב:


class ProductFactory
{
    public static function build($type) {
        // assumes the use of an autoloader
        $product = "Product_" . $type;
        if (class_exists($product)) {
            return new $product();
        }
        else {
            throw new Exception("Invalid product type given.");
        }
    }
}

מה שה-class הזה עושה זה לקבל פרמטר, לבצע instance ולהחזיר את האובייקט החדש והנוצץ למי שקרא אותו. במידה ואין מוצר כזה – Exception יבשר לנו על זה בצורה מסודרת.

כמובן שזו רק הדגמה שטחית ומאד מאד בסיסית ל-factory, במקור ה-factory יכול לעשות הרבה יותר מאשר טעינה בלבד של קובץ ויצירה של אובייקט – מה בדיוק? זה תלוי בכם ובמה שאתם צריכים. אבל כדאי מאד להשתמש ב-Factory שמלבד MVC היא אחת מתבניות העיצוב הפופולריות ביותר. יש הגדרות יותר מתקדמות ל-Factory שבהם מגדירים מה 'מותר' ומה 'אסור', אני אוהב להראות דברים בת'כלס – ובת'כלס ככה עובד Factory. אם להשתמש בו או לא, זו הבחירה שלכם.

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

יסודות בתכנות

מספרים בינאריים בקוד

איך, ויותר חשוב למה, משתמשים במספרים בינאריים בתכנות? גם בפייתון ובג׳אווהסקריפט?

פתרונות ומאמרים על פיתוח אינטרנט

עבודה עם GPT למתכנתים

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

ספריות ומודולים

להתנסות ב AutoGPT

הטרנד החם בעולם ה-GPT וה-AI – הפעלת אייג׳נטים בקלות עם Auto GPT.

גלילה לראש העמוד