|
|
|
המבנה הכללי:
להלן המבנה הכללי של ה template method. אם אינכם זוכרים כיצד לקרוא את הדיאגרמה הבאה זה הזמן
להתרענן .
|
לחץ להגדלה - template method
|
מיהם החברים בחגיגה?:
- AbstractClass (Application) - מגדיר פעולות פרימיטיביות אבסטרקטיות שה concrete subclass מממש על מנת לממש צעדים של אלגוריתם. מממש template method שמגדירה את השלד של אלגוריתם. ה template method קוראת לפעולות הפרימיטיביות כמו גם לפעולות שממומשות ב AbstractClass או באובייקטים אחרים.
- ConcreteClass (MyApplication) - מממש את אותן פעולות פרימיטיביות שיועדו להיקבע על ידיו.
מתי נשתמש בtemplate method pattern?:
- כדי ליישם חלקים אינווריאנטים באלגוריתם פעם אחת ולהשאיר ל subclass ים לממש את חלקי ההתנהגות שמשתנים.
- כאשר ישנה התנהגות משותפת בין subclass ים, ונרצה להפריד אותה ולרכז אותה ב class נפרד על מנת להימנע משכפול קוד. תחילה אנו מזהים את ההבדלים בקוד קיים ולאחר מכן מפרידים את ההבדלים לפעולות חדשות. לבסוף, מחליפים את הקוד שמשתנה באחת מהפעולות החדשות, והיא תקרא על ידי template method.
- כדי לשלוט במידת ההרחבה שמתבצעת על ידי ה subclass ים. אפשר להגדיר template method שקוראת לפעולות אבסטרקטיות בנקודות מסוימות, ובאופן זה אנו מאפשרים הרחבה רק בנקודות אלה.
יחסי העבודה:
- ConcreteClass מתבסס על AbstractClass שיממש את הצעדים האינווריאנטיים באלגוריתם.
יתרונות וחסרונות: .
template methods הן טכניקה בסיסית עבור reuse של קוד. בפרט הן חשובות בספריות של
class ים, מכיוון שהן, למעשה, האמצעים להפרדה וריכוז של התנהגות משותפת ב
class ים שמיועדים לספריות.
מעניין לשים לב שכאן ה parent class קורא לפעולות של ה subclass, וזה ההפך מבדרך כלל: בדרך כלל ה subclass קורא לפעולות של parent class. template methods קוראות לסוגים הבאים של פעולות:
- concrete operations - פעולות שמתבצעות על ConcreteClass או על קליינטים.
- concrete AbstractClass operations - כלומר, פעולות שהם שימושיות עבור subclass ים ושבדרך כלל subclass ים קוראים להן מתוך פעולות של עצמם.
- primitive operations - כלומר פעולות אבסטרקטיות שמוגדרות ב AbstractClass וממומשות ב subclass ים.
- factory methods - ראה factory method.
- hook operations - מספקות התנהגות ברירת מחדל אשר subclass ים יכולים להרחיב אם יש בזה מן הצורך. hook operation בדרך כלל לא מבצעת כלום בתור ברירת מחדל.
אחד היתרונות ב template method הוא באפשרות ל hook operations. ב template method חשוב לפרט אילו פעולות הן hook operations (כלומר ניתן לדרוס אותן) ואילו פעולות הן abstract operations (כלומר
חייבים לדרוס אותן). כדי לעשות reuse ב class אבסטרקטי באופן אפקטיבי, הכותבים של ה subclass חייבים להבין אילו פעולות יש לדרוס ולממש מחדש. נראה מהו היתרון ב hook operations:
subclass יכול להרחיב פעולה של parent class על ידי דריסה של הפעולה וקריאה לפעולה של ה parent מתוך המימוש החדש באופן מפורש:
void DerivedClass::Operation() {
// DerivedClass extended behavior
ParentClass::Operation();
}
לצערנו קל לשכוח לקרוא לפעולה הנורשת בסוף המימוש ב subclass הנורש. הפתרון הוא שנוכל להפוך פעולה כזו ל template method על מנת לתת לparent שליטה על האופן בו subclass ים ירחיבו אותו. ואז הרעיון יהיה לקרוא ל hook operation מתוך ה template method ב parent class. ה subclass ים ידרסו את ה hook operation הזו במידת הצורך:
void ParentClass::Operation() {
// ParentClass behavior
HookOperation();
}
HookOperation() לא עושה כלום ב ParentClass:
void ParentClass::HookOperation() { }
subclass דורסים את HookOperation() על מנת להרחיב את
ParentClass::Operation():
void DerivedClass::HookOperation() {
// derived class extension
}
|
|
|
|