תבניות עיצוב בג'אווה סקריפט – Factory Pattern

Published on
Authors
  • avatar
    Name
    Yonatan Snir

תבנית תכנון זאת נופלת תחת הקטגוריה של – Creational design patterns. תבניות שנופלות תחת הקטגוריה הזאת בדרך כלל מספקות לנו דרך ליצירת כמות גדולה של אובייקטים שונים ואפשרות להשתמש באותו קטע שוב ושוב על מנת לנהל או ליצור את האובייקטים הללו.

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

אז התשובה היא פשוטה. יצירת אובייקטים חדשים מאותו הסוג בכל פעם במקומות שונים בקוד יכולה לסרבל לנו את הקוד ולבלגן אותו. עוד פעם להשתמש ב-const או let, עוד פעם לכתוב את אותן המפתחות והמתודות, וכ"ו… לעומת זאת, אם נשתמש באובייקט אחד שהוא ייצר לנו אובייקטים חדשים – הקוד יישאר נקי מסודר וקצר יותר. יהיה לנו את האובייקט הראשי שהוא בעצם ה"מפעל" שלנו והוא ישב במקום מסוים בקוד, ובכל פעם שנרצה ליצור אובייקט מסוג מסוים חדש – פשוט נקרה לו! הללויה!

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

function Designer(name){
   this.name = name;
   this.type = "Designer";
}
function Developer(name){
    this.name = name;
    this.type = "Developer";
}

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

function EmployeeFactory(){
    this.add = (name, type) => {
        switch (type){
            case 1:
                return new Developer(name);
            case 2:
                return new Designer(name);
            default:
                return;
        }
    }
}

כתבנו אובייקט עם הפונקציה add שהפונקציה הזאת בעצם מוסיפה לנו עובדים חדשים לפי מה שנגדיר ב-type. במקרה נשלח 1, המפעל ייצר לנו מפתח. אם נגדיר 2, המפעל ייצר לנו מעצב. זהו! המפעל שלנו מוכן ומזומן, אך עדיין לא עובד. נשאר לנו רק "להפעיל" אותו.

const empFactory = new EmployeeFactory();

טה דם! סיימנו. עכשיו אם נרצה ליצור כמה עובדים חדשים:

const employees = [];
employees.push(empFactory.add('Yonatan', 1))
employees.push(empFactory.add('Eva', 1))
employees.push(empFactory.add('Noa', 2))

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

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

function sayHi(){
    console.log(`Hey! my name is ${this.name} and I'm working as a ${this.type}`)
}
employees.forEach(emp => sayHi.call(emp))

והפלט:

Hey! my name is Yonatan and I'm working as a Developer
Hey! my name is Eva and I'm working as a Developer
Hey! my name is Noa and I'm working as a Designer

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