MasterDK פורסם 2009 בנובמבר 28 Share פורסם 2009 בנובמבר 28 זו בעיה דיי ידוע ואני מחפש אליה את הפתרון הפשוט ביותר והטוב ביותר.תיאור הבעיה:נתונה מחלקה BasePacket שממשת את האינטרפייס Serializable.למחלקה יש בנים כגון: LoginPacket, LoginFailPacket, PingPacket, PongPacket וכדומה (רמת ההורשה היא 1, כלומר ל BasePacket אין נכדים רק בנים).נתונים שתי לקוחות A ו B שיש ביניהם סוקט פתוח והם מדברים בפרוטוקול מסויים ששולח את אחת ממחלקות הבנים של BasePacket (היא עצמה אבסטרקטית ולכן לא ניתן לשלוח אותה). תהליך שליחת חבילה LoginPacket מ A ל B נראה ככה:LoginPacket login = new LoginPacket(.., .., ..); X x = Serialize(login);Send(x);בואו נצא מהחנה ש Serialize עושה סריאליזציה ומחזיר אובייקט מסוג מסויים אשר ניתן לשליחה בסוקט, ו Send שולח את הבוייקט הזה.בצד B זה נראה ככה:while(noData()) {}X x = Receive();BasePacket packet = Deserialize(x);NeededType p = ???(packet);DoSomething(p);מקבלים את אותו X ש A שלח, עושים לו תהליך הפוך ומקבלים BasePacket. עכשיו תלוי במידע שקיבלתי אני צריכים לעשות דברים שונים (קיבלתי לוגין צריך לודא מידע ולשלוח תשובה, קיבלתי פינג צריך לשלוח פונג וכו') הבעיה היא שאני לא יודע מה קיבלתי. אחת הדרכים זה לעשות if-else ארוך עבור כל בן של BP ולבדוק האם packet הוא מסוג לוגין אחרת האם הוא מסוג פינג אחרת האם... וכו'. דרך אחרת דיי דומה לקודמת היא להוסיף שדה ל BP שיכיל מספר ייחודי שמתאר אחד לאחד את אחד הבנים שלו ואז לעשות משהוא כזה:if(packet.pType == PACKET_LOGIN)doLogin((LoginPacket)packet);else if(...)...ניסיתי לתאר כמה שאפשר את הבעיה ואם משהוא לא מובן אני יכול לנסות שוב.אשמח לדעת על פתרון יפה לבעיה הנ"ל.תודה רבה מראש! קישור לתוכן שתף באתרים אחרים More sharing options...
Zelig פורסם 2009 בנובמבר 28 Share פורסם 2009 בנובמבר 28 נחלק לשתי בעיות:1) איך לדאוג שעבור מידע מסוג X תקבל אוביקט מסוג X בתוך B.2) איך לדאוג שעבור כל X תתבצע הפעולה הנכונה.אחרי שפתרת את (1) התשובה ל-(2) ברורה - פולימורפיזם, כלומר קריאה למתודה וירטואלית (ב-JAVA כל המתודות ויטואליות בברירת מחדל).יש design pattern (ולמעשה יש משפחה שלמה) שנקראת factory (יש כל מני וריאציות). תחפש על זה.הרעיון המרכזי: יש לך פונקציה (מתודה, לא משנה) שמקבלת נתונים ומחזירה איזשהו base class, אבל הטיפוס הקונקרטי של מה שהיא מחזירה תלוי בנתונים. כלומר הפונקציה מקבלת נתונים ומייצרת מחלקה מהטיפוס הנכון.שיטה שתתאים לך: תייצר interface שנקרא לו נניח PacketHandler ויש לו מתודה אחת בשם HandlePacket (זה שם לא כ"כ מוצלח אבל נלך על זה) שעושה את העבודה של B עבור כל טיפוס. תממש מספר handler-ים מהטיפוסים המתאימים: PingHandler, LoginHandler וכו'.עכשיו אתה צריך איזהו factory שמקבל את x ומחזיר PacketHandler.HandlerFactory factory = ....;X x = Receive();PacketHandler handler = factory.CreateHandler(x);handler.HandlePacket();ונחזור לשאלה המרכזית: איך לייצר את הטיפוס הנכון בתוך ה-factory? יש מספר שיטות.אחת היא כמו שהצעת, if-else. זה לא ממש טוב.הבאה היא בעזרת switch. זה כבר יותר טוב, ואפילו מתאים למקרים פשוטים, אבל גם לו יש בעיות.עוד שיטה היא בעזרת מפה: תכין מפה שממפה את הטיפוס (נניח שהוא int) ל-factory מתאים אשר יודע לייצר אובייקטים מהסוג הנכון.הנה לך הסבר: http://en.wikipedia.org/wiki/Abstract_factory_pattern קישור לתוכן שתף באתרים אחרים More sharing options...
MasterDK פורסם 2009 בנובמבר 28 מחבר Share פורסם 2009 בנובמבר 28 תודה רבה על ההסבר!זה באמת עזר!שוב תודה! קישור לתוכן שתף באתרים אחרים More sharing options...
Zelig פורסם 2009 בנובמבר 29 Share פורסם 2009 בנובמבר 29 בהצלחה.אפ זה מעניין אותך, אני ממליץ שתקרא קצת על design patterns. מעין סט של פתרונות ידועים לבעיות שצצות הרבה.אני מצאתי שהספר הזה די מועיל וקריא: http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612 קישור לתוכן שתף באתרים אחרים More sharing options...
MasterDK פורסם 2009 בנובמבר 29 מחבר Share פורסם 2009 בנובמבר 29 בהצלחה.אפ זה מעניין אותך, אני ממליץ שתקרא קצת על design patterns. מעין סט של פתרונות ידועים לבעיות שצצות הרבה.אני מצאתי שהספר הזה די מועיל וקריא: http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612כן תודה רבה אני מכיר את זה כבר, פשוט לא הצלחתי לשלב את אחד ה patternים לבעיה שלי (חוסר ניסיון אני מאמין).שוב תודה! קישור לתוכן שתף באתרים אחרים More sharing options...
Recommended Posts
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.