תבנית Factory Method

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש
שיטת המפעל ב-UML

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

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

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

דוגמה[עריכת קוד מקור | עריכה]

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

public interface ImageReader 
{
     public DecodedImage getDecodedImage();
}
 
public class GifReader implements ImageReader 
{
     public GifReader( InputStream in ) 
     {
         // check that it's a gif, throw exception if it's not, then if it is
         // decode it.
     }
 
     public DecodedImage getDecodedImage() 
     {
        return decodedImage;
     }
}
 
public class JpegReader implements ImageReader 
{
     //....
}

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

public class ImageReaderFactory 
{
    public static ImageReader getImageReader( InputStream is ) 
    {
        int imageType = figureOutImageType( is );
 
        switch( imageType ) 
        {
            case ImageReaderFactory.GIF:
                return new GifReader( is );
            case ImageReaderFactory.JPEG:
                return new JpegReader( is );
            // etc.
        }
    }
}

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

מגבלות[עריכת קוד מקור | עריכה]

קיימות מספר מגבלות אשר קשורות לשימוש במתודת מפעל ובהן:

  • שכתוב של מחלקה כך שתיבנה באמצעות Factory Method מפירה את החוזה עם לקוחות המחלקה. למשל אם המחלקה Complex הייתה מחלקה רגילה אז היו לה וודאי לקוחות רבים המאתחלים אותה כך :
    Complex c = new Complex(-1, 0);
    
    ברגע שמכירים בכך ששתי מחלקות מפעל שונות נחוצות משנים את קוד המחלקה לקוד שהודגם קודם אולם כעת הבנאי הוא private ולכן הקוד של הלקוח אינו עובר הידור.
  • מאחר שהתבנית מתבססת על שימוש בבנאי private המחלקה לא יכולה להיות מורחבת.
  • כשמרחיבים את המחלקה (כאשר הופכים את מתודה הבנאי ל-protected) אז תת-המחלקות חייבות לספק את המימוש שלהן לכל מתודות המפעל.

שימושים[עריכת קוד מקור | עריכה]

  • ב-ADO.NET,‏ IDbCommand.CreateParameter הוא דוגמה לשימוש בתבנית עיצוב זו.
  • ב-Qt,‏ QMainWindow::createPopupMenu היא שיטה המשתמשת בתבנית עיצוב זו המוגדרת בתשתית שניתן לרמוס בקוד האפליקציה.
  • ב-Java, יש שימוש בתבנית עיצוב זו מספר פעמים במארז (package)‏ javax.xml.parsers . דוגמאות לכך הם javax.xml.parsers.DocumentBuilderFactory או javax.xml.parsers.SAXParserFactory.

מקורות[עריכת קוד מקור | עריכה]

קישורים חיצוניים[עריכת קוד מקור | עריכה]