הכרנו בפעמים הקודמות את הDesign Pattern ששמו Visitor.
בשני המימושים שראינו היו שתי מחלקות:
הVisitor, עם הפונקציה שמקבלת את הElement, האחראי על הפעולה שאנחנו רוצים לבצע
|
|
והElement, עם הפונקציה שמקבלת את הVisitor, המספר לנו איך לטייל עליו
|
|
מצד אחד זה בסדר, מאחר והפונקציה של הElement מספרת לנו איך לטייל עליו, ואילו הVisitor רק צריך לדעת איזו פעולה להפעיל.
מצד שני, זה קצת מגביל אותנו. אם המחלקות של הElementים הן לא שלנו, ואנחנו רוצים "להוסיף" להן פונקציה וירטואלית, די נתקשה להוסיף את הפונקציה Visit אליהן.
מה אפשר לעשות? נניח לרגע שאנחנו מוותרים על האחריות של הElement לספר לנו איך לטייל עליו.
נניח שהמחלקות שיורשות מCarElement הן לא שלנו, ואנחנו מעוניינים לעשות משהו כזה: אנחנו מעוניינים לכתוב פונקציה בשםToXElement היוצרת מהInstanceים איזשהו Xml המתאר אותן.
אז נוכל לעשות משהו כזה:
ניצור מחלקת Visitor כמו פעם קודמת:
|
|
שתמומש כך:
|
|
כעת לכל טיפוס ניצור Overload מתאים:
|
|
בזמן ריצה מפוענח הOverload המתאים ביותר, אליו ניגשת הפונקציה ToXElement.
אם למשל נכתוב את הקוד הבא, נקבל את הפלט:
|
|
שזה די מגניב.
שימו לב שהדבר הזה מאפשר לנו "להוסיף" פונקציות וירטואליות גם למחלקות שהן לא שלנו.
עם זאת הפסדנו משהו. אם במימוש הקודם הVisitor לא היה צריך להכיר את המבנה של האובייקט שלנו, עכשיו הוא צריך. (הדבר מתבטא בInnerToXElement של Car).
לעומת זאת, כאשר אין ברירה, המימוש הזה יכול להיות שימושי, למרות שהוא מצריך מאיתנו לעשות שני דברים: להתעסק בטיול על האובייקט, ובטיפול בו.
יום דינאמי טוב