Factory
Plugin

../images/Emo26.gif Factory ../images/Emo26.gif Plugin

1. קראתי על ה Design Pattern שנקרא Factory, שמטרתו היא ליצור ולספק Instances של אובייקטים שונים. מישהו יכול לתת דוגמא לצורך שכזה ? 2. שמעתי על מונח שנקרא Plugin, בהקשר של טעינה דינאמית של רכיבים, לדוגמא, יש לי קובץ XML המכיל רשימה של DLL, ובכל רגע נתון אני יכול להוסיף לשם שורה נוספת, ומה שהמערכת עושה זה לקרוא את הרשימה, לטעון את ה DLLים (REFLECTION), ולספק אינסטנסים שלהם. מישהו מכיר ? המונח נכון ? אפשר דוגמא ?
 
../images/Emo20.gif HashTable ?

אני רץ על קובץ גדול, המכיל מספרים רבים, אני רוצה בסופו של דבר לקבל רשימה של מספרים, כאשר כל מספר מופיע פעם אחת בלבד. איזה מבנה נתונים מתאים ? חשבתי על HashTable, אבל אין לי כאן Key ו Value... חשבתי על מערכת, אבל אני לא רוצה לסרוק שוב ושוב את המערך עבור כל מספר שבקובץ.. רעיונות ?
 

עידו פ

New member
תלוי בסביבת הפיתוח שלך

א. אפשר להשתמש ב-hashtable (מקסימום שה-key יהיה המספר וה-value יהיה ... גם המספר !). ב. אם יש לך מערכים בגודל דינמי, שמאפשרים איתור איבר בפקודה אחת, כגון מחלקת List בדוט נט (מתודה Contains) - גם אופציה יש עוד המון שיטות אחרות - בניית מבנה נתונים dictionary, כתיבה ל-DB ושליפת distinct ועוד ועוד שיטות מטופשות שזמן הכתיבה שלהן יהיה פי 100 מזמן ההרצה של אחת האפשרויות הראשונות.
 
תודה רבה, יש הבהרות קטנות :

א. פשוט ונכון, להשתמש ב HashTable כשה Key וגם ה Value יהיו המספר
, בפעם הראשונה במספר יכנס ל Hash, בפעם השניה גם יכנס, ובעצם לא יהיה שינוי. ב. מחלקת List קיימת ב FW 1.1 ? היא דינאמית מבחינת הקצאת הזכרון לאיברים ? (נסתר ממני כמובן) תודה !
 

עידו פ

New member
-->

א. נכון ב. קיימת למיטב זכרוני, דינמית למיטב זכרוני וממש לא משנה איך היא מקצה את הזכרון, בהנחה ועבור כמות איברים גדולה היא נותנת ביצועים מניחים את הדעת.
 
../images/Emo20.gif קיימת שפה עם המרה הפוכה ?

אם יש לי מחלקת בסיס (Base) ומחלקה יורשת (Derived) : (לא מציג מתודות / קונסטרקטור, רק את המידע לצורך הדוגמא)
Public Class MyBase { int _a; } Public Cass MyDerived : MyBase { int _b; }​
אני יכול לבצע :
MyDerived myD = new MyDerived(); MyBase myB = (MyBase)myD;​
האם יש אפשרות כלשהיא להמיר מ Base ל Derived, תוך השלמת הנתון החסר ? למשל :
MyBase myB = new MyBase(); MyDerived myD = (MyBase)myB(_b = 3);​
 

עידו פ

New member
לא דרך constructor

לרוב אם מגיעים למצבים שצריכים לממש דברים כאלו לא עושים את זה ע"י ירושה (derived לא יירש מ-base), אלא ההגדרה של מחלקת ה-derived תהיה ע"י הגדרת association למחלקת base (או ליתר דיוק composition). ואז אפשר להעביר בקונסטרקטור של derived אובייקט מסוג base ועוד פרמטרי ברירת מחדל, ולאתחל את המאפיין של ה-association ל-base (כך אתה משמר את ה-reference לאובייקט המקורי). אם אתה גם צריך את סט המאפיינים והמתודות שיש ב-base, תגדיר interface ש-base ו-derived יממשו, ו-derived פשוט יפעיל את המתודות ויפנה למאפיינים של base על כל הפעלת מתודה / גישה למאפיין שקשור ל-Interface. ד"א, לשיטה הזו קוראים delegate
 

עידו פ

New member
לגבי 1

ראשית כל, יש להבדיל בין Abstract factory ל-Factory method - הרעיון הבסיסי בשניהם הוא זהה, אבל כל אחד נועד ליישום של גישה אחרת. ראיתי שנתנו לך כמה דוגמאות בפורום דוט נט, אבל הנה דוגמה למימוש אחד מהפרויקט שלנו (דרך אגב, במקרה שלי מדובר ב-factory method, לגבי abstract factory לא יצא לנו לממש את ה-DP הזה) : - מסך חיפוש מבוסס MetaData - כל שדות החיפוש האפשריים מוגדרים ב-Metadata כאשר ההגדרה מכילה את סוג השדה, וולידציות ועוד. קיימת מתודת Factory שיודעת לייצר פקדי הזנה שכולם יורשים מאיזשהו Interface בסיסי המספק מידע לגבי התוכן של השדה. לאחר בניית המסך, כל מה שנותר הוא לעבור על כל הפקדים לפי ה-Interface ו"לחלוב" את התוכן שלהם ולשלוח למנוע החיפוש. הרעיון של ה-Factory במקרה זה הוא יצירה דינמית של פקדים, עפ"י הגדרת טיפוס הפקד מראש ב-Metadata כאשר כל הפקדים מקורם ב-Interface שבו ניתן להשתמש בשביל לקבל מידע על תוכן הפקד.
 
אם הבנתי נכון את הדוגמא שלך..

לא מדובר בפולימורפיזם ? כלומר, אתה עובר על כל הפקדים, מבלי לדעת איזה פקד אתה מחזיק "ביד" ברגע נתון, אבל מכיוון שכולם מממשים את אותו ממשק, אין בעיה לקבל את המידע הרלוונטי...
 

עידו פ

New member
אכן

אחת המשמעויות של factory method הינה שהמחלקה עליה אתה עובד היא מחלקת בסיס, אך אתה מכיר אותה כמחלקת האב שלה (מאחר ו-factory method מחזיר מחלקות בן שכולן יורשות מאב משותף), וזה העקרון של פולימורפיזם.
 
למעלה