On this page
מערך שיעור: SOLID — SRP ו-OCP
משך: 2 שעות אקדמיות (90 דקות).
מטרת השיעור: הסטודנטים יזהו הפרת SRP בקוד קיים ויפרקו אותו נכון, ויישמו OCP באמצעות abstract class/פולימורפיזם.
בסוף השיעור הסטודנטים צריכים: להסביר SRP במושג “אחריות” (לא “מתודה אחת”), לפרק מחלקה עמוסה לכמה מחלקות ממוקדות, ולהוסיף התנהגות חדשה לפי OCP בלי לגעת בקוד קיים.
דגש קריטי: OCP הוא בעצם שימוש-מכוון בכלים שכבר נלמדו (abstract/פולימורפיזם) — הדגישו שזה לא כלי חדש, אלא מסגור-מטרה לכלים קיימים.
מהלך השיעור
| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| פתיחה וחיבור | 5 דקות | הראו Invoice עם 3 אחריות מעורבבות — “מה קורה כשמשנים את פורמט המייל?” |
| הבעיה: אחריות מעורבבת | 10 דקות | הדגישו סיכון בשינוי לא-קשור ששובר לוגיקה אחרת |
| הרעיון: SRP | 20 דקות | פירוק Invoice לשלוש מחלקות ממוקדות |
| הבעיה: הוספת סוג הנחה עם if/switch | 10 דקות | הראו קוד עם if מתרחב בכל פעם שמוסיפים סוג הנחה |
| הרעיון: OCP | 20 דקות | DiscountStrategy — הוספת מחלקה חדשה בלי לגעת בקיים |
| קשר SRP↔OCP | 10 דקות | הסבירו למה מחלקה ממוקדת קלה יותר להרחיב בבטחה |
| תרגול מודרך | 15 דקות | תרגיל 1+2 |
דגשים להעברת השיעור
- תקנו מיד תפיסה שגויה נפוצה: SRP לא אומר “מתודה אחת למחלקה” — זה יגרום לפירוק-יתר מיותר. המדד הוא “אחריות” (מושג עסקי), לא ספירת מתודות.
- OCP חשוב שיורגש כ"אותם כלים, מטרה חדשה" — לא נושא נפרד. אם סטודנטים כבר שולטים ב-abstract/virtual/override מהיחידה הקודמת, זה שיעור על מתי ולמה להשתמש בהם, לא איך.
- דוגמת ה-
if/switchשמתרחב בכל הוספת סוג הנחה היא ההוכחה החיה הכי טובה ל"למה OCP" — הראו אותה ולא רק תארו אותה.
מושגים
SRP — לכל מחלקה סיבה אחת להשתנות (אחריות אחת). OCP — פתוח להרחבה, סגור לשינוי. “סיבה להשתנות” — קבוצת דרישות עסקיות שמשפיעות על אותו קוד יחד.
תרגיל חשיבה
שאלת פתיחה: “יש לכם מחלקה ReportGenerator שגם מחשבת נתונים, גם מעצבת HTML, וגם שולחת למדפסת. מנהל המוצר מבקש לשנות רק את עיצוב ה-HTML. מה הסיכון?”
מהלך: תנו לסטודנטים לזהות שהשינוי (בעיצוב בלבד) עלול בטעות לפגוע בקוד החישוב או ההדפסה שיושב באותה מחלקה — לא כי מישהו התכוון לכך, אלא כי הכל “צפוף” יחד. זו בדיוק ההגדרה המעשית של הפרת SRP: שינוי בסיבה אחת (עיצוב) מסכן קוד שקשור לסיבה אחרת (חישוב/הדפסה).
מה המרצה מראה בסוף: פרקו יחד את ReportGenerator ל-ReportCalculator/ReportFormatter/ReportPrinter, והראו ששינוי ב-ReportFormatter בלבד עכשיו לא יכול “לגעת” בקוד החישוב כלל — הם פשוט בקבצים/מחלקות נפרדות לגמרי.