תיכנון ירושות בצורה נכונה

yosi44441

New member
תיכנון ירושות בצורה נכונה

אני מדבר על C# אבל כמובן רלוונטי לכל שפה
יש לי מערכת לקריאה כרטיסים
אני חושף למשתמש בסה"כ read ו write
לכל כרטיס יש property נוספים כמו שם הכרטיס, גודל הזיכרון , ייצרן וכו'
אובייקטים לדוגמא במערכת
SimCard SdCard MicroCard וכו'
בד"כ ממה שאני יודע נהוג שאת הממשק של המשתמש עוטפים ב interface
כך שנגדיר ICardהמכיל void read void write
הבעיה בINTERFACE שאי אפשר להוסיף לו property
חשבתי שנכון "להכריח" שכל אובייקט CARD , יכיל את הpropery הנ"ל(ייצרן שם וכו') .
ולכן חשבתי להגדיר מחלקה abstract שיורשת מ ICard והיא מכילה את הpropery הנ"ל, ואז כל CARD יורש מ הABSTRACT וממילא יורש מה INTERAFCE
האם זה נכון לעשות כך?
האם אפשר להכריח property ע"י מחלקה abstract?

בנוסף, ישנם תתי פונקציות שהם לא חשופות למשתמש אבל נראה לי נכון שיהיו בכל CARD ,
לדוגמא GetCardXXX , פונקציה לשימוש פנימי של כל CARD ולא חשופה ליוזר
האם נכון לשים אותה כ PRIVATE ב INTERFACE ? או במחלקה ה ABSTRACT?
תודה רבה
 

Guy Yafe

New member
נשמע שבמקרה שלך, עדיף לא להשתמש בממשקים

אם יש לך מחלקה שיש בה קוד משותף, אתה יכול לוותר על הממשק ולכתוב מחלקה אבסטרקטית.
מעבר לזה: למה בעצם אתה צריך מחלקה אבסטרקטית? למה לא להכניס את כל הקוד למחלקה אחת?
 

Guy Yafe

New member
ממשק ו - interface זה אותו דבר.

פשוט בשפות שונות.
הנקודה שלי היא שאתה יכול לוותר על זה
 

yosi44441

New member
אבל...

נהוג לתת למשתמש "ממשק" דרך מחלקה ABSTRACT?
למה לא לעשות את הממשק הראשי READ WRITE דרך אינטרפייס ומחלקה אבסטרקטית שתירש מהINTERFACE ותוסיף עוד דברים כמו שדות/קוד משותף?
כמו כן, כיצד ניתן לחייב הופעה של PROPERTY ב ABSTRACT?
כי אם אני יוצר int Id{set;get; במחלקה האבסטרקטית, ולא כותב את זה במחלקה היורשת זה כן מתקמפל
 

Guy Yafe

New member
אין עניין של נהוג ולא נהוג.

יש עניין של נחוץ ולא נחוץ.
אם אתה צריך לתת למשתמש איזשהו ממשק, אז אכן זה הפתרון. אבל אתה בטוח שאתה צריך לתת למשתמש ממשק?
מי המשתמש שלך? האם יהיו כמה שימושים שונים לממשק? האם חשוב לך להכמיס ממנו את המימוש הקונקרטי?
&nbsp
ממשק מיועד להכמיס פונקציונליות מסויימת.
לעומתו setters/getters מתארים תוכן ובדרך כלל לא רלוונטיים לממשקים. אם יש לך אובייקט שמכיל תוכן מסויים, עדיף שהוא לא יכיל פונקציונליות ולהיפך.
&nbsp
ספר יותר על הפרוייקט שלך ויהיה יותר קל לעזור לך.
 

yosi44441

New member
פשוט מאוד

יש לי GUI פשוט מאוד
איוזר צריך לראות את התוכן של הכרטיס
כותב לתוכו וקורא מתוכו
 

Guy Yafe

New member
מי המשתמש?

האם זה פרוייקט לימודי או שזה פרוייקט עסקי, בו אתה חושף SDK ללקוח?
האם יש הבדל מהותי בין הכרטיסים? יכול להיות שבכלל אתה לא צריך מחלקה אבסטרקטית או ממשקים.
 

yosi44441

New member
לימודי

הכרטיסים שונים באופן הקריאה והכתיבה
למה שלא יצטרך ממשק/אבסטרקט? זה יותר מסדר את הקוד ונותן צורה נוחה לשינויים והוספה
 

Guy Yafe

New member
ומה הפונקציונליות של הכרטיס?

מה משותף לכל הכרטיסים ומה שונה ביניהם?
 

nocgod

New member
אפשר לעשות את מה שאתה רוצה

גם עם interface - כי אתה כן יכול לשים property על interface ואז לממש אותו כמה שבא לך
אפשר לעשות את מה שאתה רוצה גם באמצעות מחלקה abstract ולרשת אותו כמה שאתה רוצה.

אני נוהג להמנע מירושות מיותרות ובכל פעם שאני יכול להשתמש בinterface כדי להשיג את המטרה שלי בלי לעקם את הדיזיין אז אני אעדיף interface
הנה קוד דוגמא
בכל מקרה - צריך להבין בדיוק מה ה usecase שלך אולי אתה בכלל לא צריך הבדלה בין מחלקות הכרטיסים...
* אני משחק קצת עם תחביר של C#7 אז אולי יהיו שם דברים שאתה לא מכיר - על הדרך תכיר, ואולי יהיו שם דברים שכתובים קצת מכוער (נגיד אני עדיין לא סוגר אם אני אוהב את הצורה שבה כתבתי את הבדיקות וההשמות בconstructor)
 

yosi44441

New member
תודה

עזרת לי מאוד
כמה שאלות ברשותך
1-חשבתי שאי אפשר לשים שדות באינטרפייס, ההבדל שזה property עם SET או GET אז זה כמו פונקציה ולכן אפשר?
2- החיסרון במימוש שלך שאי אפשר לבנות CONSTRUCTOR אב שפשוט נשלח לו והוא יעשה השמה של כל הproperyהנ"ל
לכל הכרטיסים יש את אותה השמה ...חבל על הקוד הכפול
3- מה יש כאן מ גירסא 7?
 

nocgod

New member
כמה תשובות

א. אי אפשר לשים fields אבל property איננו field אז אין שום בעיה
ב. אם אתה רוצה constructor אחיד זה כבר דרישה שinterface לא כל כך יכול לענות עליה אמצעות בצורה פשוטה או יפה. הכל שאלה של דרישות בסופו של יום, תבין את הdesign, תגדיר את הדרישות, תממש.
ג. ספציפית השתמשתי ב expression exceptions ( האתחול שזורק exceptions בתוך הexpression עצמו). רציתי להוסיף עוד דברים אבל בסוף לא עשיתי...
 

nocgod

New member
לא... אבל אתה יכול לעשות initializer function שתעשה את זה...

זה לא יפה, ולא מומלץ.
שוב - אם אתה צריך דברים כאלה כנראה שאתה צריך לעשות דיזיין מחדש לרעיון שלך, או להשתמש ב creational design pattern מתאים שיעיף ממך את הכאב ראש של ייצור ה SD.
אולי אתה בכלל לא צריך מחלקות שונות בין "סוגי" הכרטיסים, אולי מחלקה אחת מתאימה לך שתקבל strategy כתיבה/קריאה בהתאם לכרטיס.
שוב הכל תלוי במה שאתה מנסה להשיג, קוד הוא פיתרון לבעיה לא הבעיה.
 
למעלה