On this page
מערך שיעור: SOLID — LSP, ISP ו-DIP
משך: 2 שעות אקדמיות (90 דקות).
מטרת השיעור: הסטודנטים ישלימו את חמשת עקרונות SOLID, ויבינו את הבסיס הרעיוני ל-Dependency Injection שיפגשו ביחידת ASP.NET Core.
בסוף השיעור הסטודנטים צריכים: לזהות הפרת LSP בהיררכיית ירושה, לפצל ממשק “שמן” לפי ISP, ולכתוב מחלקה שתלויה ב-Interface במקום במימוש קונקרטי (DIP).
דגש קריטי: הזכירו במפורש בסוף השיעור ש-DIP הוא בדיוק העיקרון שעומד מאחורי Dependency Injection — יחידת ASP.NET Core הבאה תשתמש בו בפועל דרך ה-Framework.
מהלך השיעור
| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| פתיחה וחיבור | 5 דקות | הזכירו את דילמת Square:Rectangle מיחידת הירושה |
| הרעיון: LSP | 20 דקות | הדגימו את ההפתעה בפועל (Width משנה Height) |
| הבעיה: ממשק שמן | 10 דקות | IWorker עם Eat() שרובוט מוכרח “לזייף” |
| הרעיון: ISP | 15 דקות | פיצול ל-IWorkable/IEatable |
| הבעיה: תלות ישירה במימוש | 10 דקות | OrderService עם new EmailNotifier() בפנים — קשה להחליף |
| הרעיון: DIP | 20 דקות | הזרקת INotifier דרך קונסטרוקטור |
| תרגול מודרך | 10 דקות | תרגיל 1+2 |
דגשים להעברת השיעור
- LSP קשה יותר להפנמה משאר העקרונות כי ההפרה “מתקמפלת” בסדר גמור — חשוב להריץ את הדוגמה בפועל ולא רק לתאר אותה, כדי שהסטודנטים יראו את ההפתעה בעיניים.
- קשרו DIP במפורש קדימה ל-ASP.NET Core ("
services.AddScoped<IRepository, SqlRepository>()שתראו בקרוב זה בדיוק DIP בפעולה") — נותן לעיקרון עוגן קונקרטי בעתיד הקרוב של הקורס. - ISP קליל יחסית להעברה — מספיק דוגמה אחת טובה (IWorker) בלי להכביד.
מושגים
LSP — מחלקה יורשת חייבת להתנהג נכון במקום הבסיס. ISP — עדיף כמה ממשקים ממוקדים על ממשק “שמן” אחד. DIP — תלות בהפשטה (Interface), לא במימוש קונקרטי.
תרגיל חשיבה
שאלת פתיחה: “יש לכם CheckoutService שיוצר new CreditCardGateway() בתוכו. עכשיו רוצים לבדוק אותו (Unit Test) בלי לחייב כרטיס אשראי אמיתי בכל הרצת בדיקה. איך תעשו את זה?”
מהלך: תנו לסטודנטים לחשוב על הבעיה לפני שמציגים DIP — התשובה האינטואיטיבית (“פשוט תשנו את הקוד בזמן בדיקה”) היא בדיוק מה ש-DIP פותר בצורה נקייה: אם CheckoutService תלוי ב-IPaymentGateway (הפשטה) במקום ב-CreditCardGateway הספציפי, אפשר “להזריק” MockPaymentGateway רק בבדיקות, בלי לגעת בקוד המקורי כלל.
מה המרצה מראה בסוף: הריצו את אותו CheckoutService פעמיים — פעם עם CreditCardGateway אמיתי (מדפיס “מחייב כרטיס”) ופעם עם MockPaymentGateway (מדפיס “תשלום מדומה הצליח”) — בלי לשנות אף שורה בתוך CheckoutService בין ההרצות.