ראשי > abstract factory pattern > חלק ראשון
The Abstract Factory

המטרה:
לספק ממשק ליצירת משפחות של אובייקטים שקרובים זה לזה, או קשורים באופן מסוים, או תלויים זה בזה, מבלי לפרט את ה
concrete classes שלהם.

ידועה גם בתור:
kit

מוטיבציה:
העלו בדמיונכם הפרוע אפליקציה מסוימת שתומכת במספר סטנדרטים של ממשק גרפי כמו למשל
Presentation Manager ו Motif. הסטנדרטים השונים של הממשקים מביאים לכך שכפתורים, חלונות, פסי הגלילה וכו' נראים ומתנהגים אחרת בכל אחד מהם. כמובן שהדבר האחרון שנרצה הוא לכתוב עותקים של האפליקציה לכל סטנדרט גרפי שקיים בעולם.
כדי להיות פורטביליים לרוחב הסטנדרטים השונים של הממשקים הגרפיים הקיימים ושל אלה שיתווספו, האפליקציה לא תפרט בקוד אילו אובייקטים בדיוק היא תיצור עבור כפתור, פס גלילה וכו' עבור כל סטנדרט מסוים. אם היא הייתה עושה כן זה היה מקשה לשנות את הקוד עבור כל סטנדרט מכיוון שהיינו צריכים לעבור בכל פעם על כל הקוד ולמצוא את כל המקומות שאובייקטים אלה מופיעים.

למעלה
הפתרון:
הפתרון יהיה הגדרת
class אבסטרקטי, factory, שתפקידו יהיה אחד: להגדיר את הממשק המשותף ליצירת אלמנטים (כפתור, פס גלילה, חלון וכו') בסיסיים בסטנדרטים גרפיים שונים ( PM, Motif וכו'....). לכל אלמנט כזה (כפתור, פס גלילה, חלון וכו'...) יהיה class אבסטרקטי משלו ו concrete subclasses שיממשו את האלמנט (כפתור, פס גלילה, חלון וכו'...) עבור כל סטנדרט מסוים ( PM, Motif....). בממשק של factory תהיה פעולה שמחזירה אובייקט מסוג כפתור עבור ה class האבסטרקטי של כפתור, פעולה שמחזירה אובייקט חלון עבור ה class האבסטרקטי מסוג חלון, וכן הלאה..

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

כעת, מי בכל זאת יפקח על איזה סוגי אובייקטים נוצרים? מישהו חייב לקחת אחריות על כך! אי אפשר להתחמק מכך לנצח...אם כן, יש מתנדב:
עבור כל סטנדרט (PM, Motif וכוווווו'....) יש concrete subclass ל class האבסטרקטי factory . כל subclass כזה מממש את כל פעולות יצירת האובייקטים עבור סטנדרט (PM, Motif וכו' כבר אמרתי?) מסוים. הסתבכתם קצת? אין כמו ציור כדי להבהיר את מצב העניינים ולהירגע...:

לחצו להגדלה
לחץ להגדלה - abstract factory exapmle

למי שלא זוכר את הסימונים אפשר להתרענן קצת. אם לא לחצתם, לא נורא כי נחזור תוך כדי (לאלה שלחצו: לא לכעוס, זה רק לטובתכם...:o)):
הגדרה: widget - חלק מממשק משתמש גרפי, למשל: כפתור, פס גלילה, חלון וכו'..
בציור רואים שיש מחלקה WidgetFactory אבסטרקטית (כתב מלוכסן מסמל זאת) ויש לה שני concrete classes (כתב רגיל מסמל זאת) שיורשים ממנה- PMWidgetFactory, ו MotifWidgetFactory , שהם למעשה Concrete Factory classes שמייצרים widgets. החצים המקווקוים משמעותם שה Concrete Factories (שבבסיס החץ) מייצרים אובייקטים מסוג אלה שהחץ מצביע אליהם.
כפי שאמרנו, גם לכל אלמנט יש class אבסטרקטי ו concrete classes שיורשים ממנו. כך למשל, PMWidgetFactory מימש את הפעולות האבסטרקטיות של WidgetFactory כך שייצרו אובייקטים PMScrollBar וPMWindow , בעוד שMotifWidgetFactory מימש פעולות אלה כך שייצרו אובייקטים מסוג MotifScrollBar ו MotifWindow, כאשר בשני המקרים אלו מופעים של אובייקטים מסוג scroll bar וwindow .
דבר נוסף שרואים בציור הוא שהקליינט מכיר (נמצא ביחס acquaintance - רואים זאת ע"י חץ רגיל) רק את המחלקות האבסטרקטיות של האלמנטים האלמנטים והוא יוצר את האובייקטים דרך הממשק של WidgetFactory. אין לו ידיעה לאיזה סוג של Concrete Factory הוא מצביע ואילו widgets נוצרים. כמו כן כשהוא יפנה אליהם בקשות הוא יודע, שוב, רק את הממשק שלהם ואין לו שום ידיעה מיהם באמת. לכן ההתחייבות היחידה שלו היא לממשק שמוגדר ע"י class-ים אבסטרקטיים והוא כלל אינו תלוי במימוש שלהם!
תלות שדווקא קיימת ואנחנו מעונינים בה היא התלות בין ה concrete classes של ה widgets . פס גלילה של PM חייב לבוא עם כפתור וחלון של PM בשיטה זו, ופס גלילה של Motif יבוא עם כפתור וחלון של Motif ואין אפשרות לערבב בטעות בין הסוגים שלהם כי כל תהליך הייצור נקבע ברגע שבו קבענו מיהו הConcreteFactory וכך נמנעות טעויות מיותרות שנובעות מחוסר ריכוז, עייפות וגעגועים הביתה...

למעלה







 
מה בעמוד:
 
המטרה
המוטיבציה
הפתרון