שימו לב ש Operation() עצמה היא פונקציה וירטואלית שיכולה להיות ממומשת על ידי הsubclass אבל את הקריאה ל
Notify() העברנו מהפונקציה
Operation() לפונקציה GenericOperation() וכך מובטח לנו שרק בסיום כל הפעולות יתבצע העדכון.
מודל ה push ומודל ה pull - במימוש של ה observer pattern לעתים קרובות ה subject יידרש לשדר אינפורמציה נוספת בקשר לשינוי אצלו. הוא יעביר את האינפורמציה הזו כארגומנט ל
Update(). כמות האינפורמציה יכולה להשתנות בהתאם לגישה שנאמץ. בגישה אחת, שנכנה אותה push model , ה subject שולח ל observer ים אינפורמציה מפורטת לגבי השינוי, בין אם הם רוצים או לא. בגישה שניה, שנכנה אותה pull model, ה subject אינו שולח שום אינפורמציה פרט למידע המינימלי על כך שחל שינוי כלשהו. ה observer ים שירצו ישאלו אותו יותר מאוחר באופן מפורש שאלות על מנת לגלות מהו בדיוק השינוי שהתרחש.
ה pull model מדגיש את ההתעלמות של ה subject מה observer ים שלו, בניגוד ל push model שבו ה subject יודע עליהם משהו. ה push model מקטין את האפשרות לשימוש חוזר (reuse) במחלקות האלה כי ה subject מניח הנחות בקשר ל observer ים שאינן תמיד נכונות במקרים אחרים. מצד שני הpull model עלול להיות לא יעיל מכיוון שה observer ים צריכים לגלות מה היה השינוי ללא עזרה מה subject.
פירוט השינויים שמעניינים באופן מפורש - ניתן לשפר את יעילות העדכון על ידי הרחבת ממשק ה registration ב subject כך שאובייקט שנרשם כמעוניין לקבל הודעות יוכל לפרט ברישום את סוג השינויים שהוא מעוניין לדעת עליהם. כאשר שינוי כזה יקרה ה subject יודיע
רק ל observer ים שנרשמו עבור שינוי זה. דרך אחת לתמוך בכך היא שימוש ברעיון של aspects עבור אובייקטים מסוג subject. כדי להירשם כמעוניין בהודעה על event מסוים observer ים יצורפו ל subject על ידי:
כאשר interest הוא סוג ה event שמעניין את ה observer. בזמן הודעה על שינוי ה subject מספק ל observer ים שלו את ה aspect שהשתנה כפרמטר לפעולת ה
Update() . למשל:
ריכוז האחריות לעדכונים מורכבים בתוך אובייקט - כאשר התלויות בין ה observer ים לsubject ים הם מורכבות במיוחד, יתכן ויידרש אובייקט מיוחד שיהיה אחראי לאחזקה ותפעול של היחסים ביניהם. נקרא לאובייקט כזה ChangeManager.
מטרתו היא להקטין את כמות העבודה הנדרשת בעת שנרצה לגרום ל observer ים לשקף שינוי שחל ב subject ים שלהם. לדוגמה, אם פעולה מסוימת משנה מספר subject ים שיש ביניהם איזושהי תלות, יתכן ונצטרך להבטיח שה observer ים שלהם מיודעים רק לאחר שכל ה subject ים גמרו להשתנות כדי להימנע מלהודיע ל observer ים יותר מפעם אחת. ל ChangeManager יש 3 תפקידים:
1. לערוך מיפוי של subject ל observer ים שלו ולספק ממשק לתחזוקה של המיפוי הזה. זה מבטל את הצורך שה subject יחזיק הצבעות ל observer ים שלו והם אליו.
2. מגדיר אסטרטגיית עדכון.
3. כשמגיעה בקשה לעדכון מ subject , ה ChangeManager מעדכן את כל ה observer ים של אותו subject.
הדיאגרמה הבאה מדגימה את הרעיון בפשטות. ישנם שם שני סוגים של ChangeManager. ה SimpleChangeManager פשוט מעדכן את כל הobserver ים של כל subject. ה DAGChangeManager מחזיק גרפים מכוונים אציקליים של תלויות בין subject ים והobserver ים שלהם. DAGChangeManager עדיף על SimpleChangeManager כאשר observer צופה ביותר מsubject אחד.
במקרה זה שינוי בשניים או יותר subject ים עלול לגרום לעדכונים כפולים ומיותרים ואת זאת ה DAGChangeManager מונע. במקרים שאין סכנה כזו נשתמש ב SimpleChangeManager. אם אינכם זוכרים את הסימונים בדיאגרמה זה הזמן
להתרענן .
לחץ להגדלה - observer - שימוש ב change manager
ולאחר שיישמנו והפנמנו את כל הנקודות למימוש נפנה למעט קוד.