שאלת מבחן בתכנות מונחה עצמים - אוניברסיטת בר-אילן 2023 - ירושה
(PyDecorator) מה מהמקרים הבאים מדגים מצב בו גם בפייתון עלינו להשתמש בתבנית העיצוב קשטן (decorator), והורשה מרובה אינה פותרת את הבעיה בצורה טובה?
.1 אמציה כותב אוסף מחלקות המייצגות את כלי הדמקה אבן שחורה, אבן לבנה, מלכה שחורה ומלכה לבנה
.2 ססיליה כותבת הרחבות לעורך טקסט פופולרי, הכוללות גרסה "מותאמת אישית" המציגה המלצות, גרסה "מתקדמת" המאפשרת צפיה בהיסטוריית עריכות הטקסט, ואפשרות שילוב ביניהן
.3 קורנליה כותבת מחלקת עץ בינארי יעיל אשר ממומש גם בעזרת מבנה מקושר וגם בעזרת מילון אשר מאפשר לקפוץ ישירות למקום מסוים בעץ
.4 נסטיה כותבת אוסף מחלקות, שכל אחת מהן מייצגת כלי שחמט כלשהו וכל אחת מהן היא גם Observable
.1 אמציה כותב אוסף מחלקות המייצגות את כלי הדמקה אבן שחורה, אבן לבנה, מלכה שחורה ומלכה לבנה
.2 ססיליה כותבת הרחבות לעורך טקסט פופולרי, הכוללות גרסה "מותאמת אישית" המציגה המלצות, גרסה "מתקדמת" המאפשרת צפיה בהיסטוריית עריכות הטקסט, ואפשרות שילוב ביניהן
.3 קורנליה כותבת מחלקת עץ בינארי יעיל אשר ממומש גם בעזרת מבנה מקושר וגם בעזרת מילון אשר מאפשר לקפוץ ישירות למקום מסוים בעץ
.4 נסטיה כותבת אוסף מחלקות, שכל אחת מהן מייצגת כלי שחמט כלשהו וכל אחת מהן היא גם Observable
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד ב2023סמסטר ב
★★★★★
ירושהמחלקותאובייקטיםתבניות עיצוב
חשבו על מצב בו נרצה לשלב מספר הרחבות ותכונות באופן דינמי. מה יקרה למספר המחלקות שנצטרך ליצור אם נשתמש בירושה עבור כל שילוב אפשרי?
התשובה הנכונה היא 2.
תבנית העיצוב קשטן (Decorator) נועדה לאפשר הוספת יכולות חדשות לאובייקטים קיימים באופן דינמי, מבלי לשנות את הקוד של המחלקות שלהם. המטרה העיקרית היא להימנע מ"פיצוץ קומבינטורי" של תת-מחלקות, שהיה נדרש אילו היינו משתמשים בירושה עבור כל שילוב אפשרי של יכולות.
במקרה של ססיליה (2), יש לנו עורך טקסט בסיסי. אנו רוצים להוסיף שתי יכולות: "המלצות" ו"היסטוריית עריכות", וחשוב מכך, לאפשר את השילוב ביניהן. אם נשתמש בירושה, נצטרך את המחלקות הבאות:
תבנית הקשטן פותרת זאת באלגנטיות. יהיה לנו אובייקט
שאר האפשרויות פחות מתאימות:
1. דמקה: זוהי היררכיית ירושה קלאסית וסטטית.
3. עץ בינארי: כאן מדובר בשתי דרכי מימוש שונות לאותו ממשק, לא בהוספת יכולות. כלומר, יש שתי אסטרטגיות מימוש שונות, אך לא שילובים שלהן.
4. שחמט: כל הכלים חולקים תכונה משותפת (להיות
תבנית העיצוב קשטן (Decorator) נועדה לאפשר הוספת יכולות חדשות לאובייקטים קיימים באופן דינמי, מבלי לשנות את הקוד של המחלקות שלהם. המטרה העיקרית היא להימנע מ"פיצוץ קומבינטורי" של תת-מחלקות, שהיה נדרש אילו היינו משתמשים בירושה עבור כל שילוב אפשרי של יכולות.
במקרה של ססיליה (2), יש לנו עורך טקסט בסיסי. אנו רוצים להוסיף שתי יכולות: "המלצות" ו"היסטוריית עריכות", וחשוב מכך, לאפשר את השילוב ביניהן. אם נשתמש בירושה, נצטרך את המחלקות הבאות:
TextEditor, CustomEditor (יורשת מ-TextEditor), AdvancedEditor (יורשת מ-TextEditor), ו-CustomAndAdvancedEditor (יורשת, אולי, משתיהן, מה שמוביל לבעיות של ירושה מרובה). אם נוסיף יכולת שלישית, מספר המחלקות הנדרש יגדל באופן מעריכי.תבנית הקשטן פותרת זאת באלגנטיות. יהיה לנו אובייקט
TextEditor בסיסי. נוכל "לעטוף" אותו באובייקט RecommendationDecorator, ואז לעטוף את התוצאה באובייקט HistoryDecorator (או בסדר הפוך). כל "קשטן" (decorator) הוא בעצמו מאותו טיפוס של האובייקט הנעטף (למשל, כולם מממשים ממשק ITextEditor), מוסיף את היכולת שלו, ומאציל את שאר הקריאות לאובייקט שהוא עוטף. כך ניתן להרכיב שילובים שונים בזמן ריצה באופן גמיש.שאר האפשרויות פחות מתאימות:
1. דמקה: זוהי היררכיית ירושה קלאסית וסטטית.
מלכה היא סוג של אבן. אין צורך בהוספת יכולות דינמית.3. עץ בינארי: כאן מדובר בשתי דרכי מימוש שונות לאותו ממשק, לא בהוספת יכולות. כלומר, יש שתי אסטרטגיות מימוש שונות, אך לא שילובים שלהן.
4. שחמט: כל הכלים חולקים תכונה משותפת (להיות
Observable). ניתן לממש זאת בקלות על ידי ירושה ממחלקת בסיס משותפת או באמצעות mixin, מבלי ליצור בעיה קומבינטורית.