Design Pattern

ייוניי

New member
Design Pattern

יש לי איזו תקיעה מחשבתית בפתרון בעיה מסויימת ואשמח לשמוע דעות והצעות. הסיטואציה הנוכחית היא שיש לנו שני ממשקים:
interface I1 { // does things... } interface I2 { void actOn(I1 someImplementationOfI1); }​
בנוסף יש לנו מחלקה שמגיעים לידיה שני אובייקטים - האחד תומך I1 והשני I2 והיא מבצעת את הקריאה למתודה המתוארת של I2 בהתאם לכך. הבעיה היא שבסיטואציות מסויימות אני אצטרך שיישום ספציפי של I2 יוכל לגשת (במהלך הרצת המתודה actOn) ליישום ספציפי של I1 באם האובייקט שהגיע שייך אליו ואם לא אז לבצע פעולות אחרות על I1 בהתאם. כמובן שאני מחפש פתרון OO ללא שימוש ב Reflection או בדיקות טיפוס בזמן ריצה. הפתרון של visitor שהוא בד"כ לא רע למצבים הללו לא מתאים לי בגלל שספציפית לא נוח לי עם העובדה שכל יישום חדש של הממשק יגרור שינוי בממשק של ה visitor (מה שבד"כ קורה ב DP הזה). על mediator חשבתי קצת אבל לא הגעתי עד הסוף איתו, אולי זה אפשרי... רמז, הכיוון הכללי שלי הוא לבצע "היכרות" מוקדמת בין היישום הספציפי של I1 ליישום I2 הספציפי המתאים לו אבל עדיין יש פה עניין בעייתי של יצירת האובייקטים וכו'... בהצלחה
 

עידו פ

New member
מה לגבי הגדרת עוד Interface ?

שייחד את המחלקות שמבצעות את היישום הספציפי שאתה רוצה ? משהו בסגנון
interface ISupportSomething { // method declarations } interface I1 class C1 : I1 class C2 : I1, ISupportSomething​
ואז במתודה של I2 לא תבדוק ישירות את טיפוס המחלקה בזמן ריצה, אלא רק תבדוק אם האובייקט שקיבלת מממש גם Inteface מסוים (ככה ניתן להרחיב את היישום הרצוי לכמה מחלקות נוספות). אם במקרה יש למה שהצעתי pattern ידוע, מה טוב
 

ייוניי

New member
זו עדיין בדיקת טיפוס בזמן ריצה...

כמובן שכשהתכוונתי ליישום ספציפי של I1 הכוונה הייתה ליישום שבסופו של דבר יתקשר עם היישום הספציפי של I2 בעזרת interface נוסף - ספציפי יותר. אבל הפתרון של בדיקת מימוש בזמן ריצה לא טוב בשבילי. קודם כל זה מחייב שמממש ISupportSomething יהיה אותו אובייקט שמממש את I1 וזה מגביל אותי. שנית ה Pattern הזה מכריח אותי לעשות את הבדיקה של "האם תומך" וכו'... בכל מימוש חדש - לא ממש שימוש חוזר יעיל בקוד.
 

עידו פ

New member
שאלה

בהנחה והמתודות באובייקט שאתה מעביר ל-I2 מקורן יהיה בהגדרת I3 ולא I1 (כפי שמשתמע מדבריך), כיצד תמנע בזמן קומפילציה העברת אובייקט למתודה ActOn שמממש את I1 אבל לא את I3 ? בהנחה ותמצא דרך, מה המתודה ActOn אמורה לעשות אם האובייקט שהועבר אליה לא מממש את היישום הרצוי ? להתעלם ? או לעשות משהו אחר במקום ?
 

ייוניי

New member
אסביר באמצעות דוגמא

אחת הדרכים הנפוצות "להגיע" ליישום ספציפי של ממשק היא ה visitor pattern. השימוש במקרה זה היה יכול להיות כזה:
public interface Visitor { void supports(I3 i3); void sorryIOnlySupport(I1 i1); } public interface I1 { void giveMeSpecificInterface(Visitor v); } class SampleI2 : I2 { public void actOn(I1 i1) { i1.giveMeSpecificInterface(new VisitorImpl()); } class VisitorImpl : Visitor { public void supports(I3 i3) { //.. } public void sorryIOnlySupport(I1 i1); { //.. } } }​
זהו בהחלט DP מוצלח ומתאים להרבה מאוד מקרים אבל כמו שאמרתי במקרה שלי אני צריך להיות יכול להוסיף ממשקים נוספים (I4, I5 וכו'...) בלי לשנות ממשקים קיימים (הם פשוט לא יהיו נגישים כקוד למי שישתמש בהם).
 
למעלה