אני משתמש במילה מבנה (structure) לתאר את התוצאה בפועל, בניגוד לתכנון (design) שזו התוכנית, או השאיפה, שלא תמיד מוסכמת על כולם או מתממשת בפועל. עצם קיומו של מסמך design לא מבטיח שלאחר שנה של קידוד – כך באמת תראה התוכנה [א].
ע״פ ריינסברגר (עוד), ישנם ארבעה אלמנטים (עם סדר עדיפויות ברור) המובילים לתוכנה פשוטה:
- כל הבדיקות עוברות.
- צמצום כפילויות קוד.
- הקוד מתאר כוונה (clarity).
- צמצום
מספר האלמנטים בקוד למינימום האפשריאלמנטים שאינם משרתים את מטרות 1-3.
כל הבדיקות עוברות
העיקרון הראשון הוא דיי ברור – התוכנה עומדת בהתנהגות הרצויה. זה הכי חשוב.
אם אתם לא משתמשים בבדיקות יחידה, אזי:
א. אתם יכולים לתרגם כלל זה ל״נכונות פונקציונליות״.
ב. אתם נמצאים בעמדת נחיתות להשגת קוד פשוט: בדיקות יחידה מאלצות את הקוד להיות מודולרי ופשוט יותר, ובלעדיהן המשימה של השגת קוד-פשוט היא קשה כפליים.
צמצום כפילויות קוד + קוד המתאר כוונה
קריאות הקוד נחשבת לעתים לחשובה לא-פחות מביטול כפילויות בקוד. ריינסברגר טוען שהסרה של קוד כפול מובילה בסה״כ לתוצאות טובות יותר מ״שימוש בקוד כפול לצורך בהירות״. ההמלצה הגורפת שלו היא להעדיף ביטול קוד כפול על פני ניסיון לכתוב קוד ברור יותר. אני נוטה להסכים, וגם מכיר בצורך לספק כללים פשוטים שקל לעקוב אחריהם, אך רוצה לציין הסתייגות בנושא זה.
הנה דוגמה של קוד \”ללא כפילויות\” שהפריע לי והפכתי לכפול:
![]() |
אני מסכים, זה לא קוד \”מושלם\”, וספריית templating הייתה יכולה להפוך אותו ליפה יותר, אך זו דוגמה אמיתית מהחיים.
הנה הקוד לאחר השינוי:
זה בהחלט קוד פשוט יותר, למרות כמה שורות קוד כפולות.
כיצד אני מסביר / מרשה כפילות קוד שכזו?
א. הכפילות קרובה פיסית – קל להבין אותה ולהיות מודעים אליה (=> הסיכוי לתקן במקום אחד ולפספס את השני – קטן).
ב. לא מדובר ביותר מ3 שורות קוד רצופות כפולות. זו דוגמה פשוטה – ביצעתי שינויים דומים לקוד ארוך ומסובך יותר (ולא רק שרשור html, אלא גם לוגיקה), אך לעולם לא השארתי יותר מ3 שורות רצופות של קוד כפול.
קוד המתאר כוונה
אם מזקקים את הכלל של \”כתיבת קוד המתאר כוונה\”, לרוב עיקר העבודה היא מסביב לשמות: שמות של פונקציות או משתנים, או שמות חדשים הנוספים ע\”י פעולות \”extract method\” או \”introduce variable\”.
ישנן 4 \”דרגות\” של שם:
- שם סתמי
- שם נכון
- שם מדויק
- שם בעל משמעות (\”meaningful\”).
שיהיה בהצלחה!
—-
[ב] אזהרה!: יש המבלבלים בין צמצום כפילות קוד בתוך המערכת, לבין שימוש-חוזר בקוד (code re-usability) או \”צמצום כפילות קוד בעולם האנושי\”. בעוד ביטול כפילות-קוד בתוך הקוד שאתם כתבתם הוא כמעט-תמיד דבר טוב, שימוש חוזר בקוד (\”חיצוני\”) הוא נושא מורכב עם הרבה ייתרונות וחסרונות. אני מתכנן לעסוק בנושא זה לעומק בפוסט נפרד.
[ג] המטאפורה הזו מטעה! מזגן הוא דבר מוכר שאנו יודעים לצפות לו ולבנות לו הכנה טובה. רוב ה\”הכנות למזגן\” בתוכנה הם ניחושים בעלטה אודות משהו לא-ידוע. בהתאמה: מנסיוני, רובן מתגלות כלא-יעילות או חסרות שימוש.
דווקא לאחרונה מרטין פאולר ניסח בצורה היפה ביותר לטעמי את סוגית ה\”מהו קוד טוב?\”. https://raw.github.com/gist/3753571/2f3a8702a0fd0ae08f9778956b8efe4d998b4d65/gistfile1.txt
תודה מוטי.תיקון קטן: נראה לי שהמקור של הטקסט הוא רוברט סי מרטין (Uncle Bob) ולא פאולר.מקור: http://goo.gl/3A4vE
היי. אהבתי את המדריך במיוחד את השיטה הפשוטה לבחירת שם . תוכל להסביר יותר על עקרון 4 ? בכללי זה נשמע הגיוני אבל גם כמו משהו שיכול למנוע מודולריות .
היי שני,אני שמח לשמוע שאהבת את הפסקה על בחירת השמות :)הכוונה בעיקרון 4 הוא *לא* להפחית את מספר המחלקות או הפונקציות במערכת (בהחלט שאיפה בעייתית: תמיד ניתן לכתוב את כל המערכת בפונקציה אחת) כי אם לחתור לצמצום מספר המרכיבים הלא חיוניים במערכת, כל אותם דברים שאנו מוסיפים \”למקרה ש…\” – מוסיפים לקוד לפני שהזדקקנו להם. דוגמה קלאסית היא לייצר מבנה של מתאם (Adapter) – כאשר יש לנו רק מימוש קונקרטי אחד או לייצר Abstract Class (או בכלל הורשה) \”עבור הרחבה עתידית\”. לא צריך את זה – YagNi.כמובן שלעתים הוספה של מרכיב לא-נחוץ למערכת יכול ליצור קוד ברור יותר – למשל Abstract Class שכל תפקידו להדגיש את ייעודה של המחלקה שיורשת ממנו. זו אפשרות סבירה המתאימה למתן העדיפויות לעיקרון 3 על פני עיקרון 4.לסיכום: אם יש אלמנט / מרכיב בקוד, שאינו נועד לגרום למערכת לעבוד, אינו מונע קוד-כפול ואינו מסביר את התנהגות המערכת (לרוב זה יהיה \”הכנה ל…משהו תיאורטי\”, או שאריות של קוד ישן שלא בשימוש) – יש לבטלו על מנת לשמור על המערכת פשוטה.אני חושב ש \”צמצום מספר האלמנטים בקוד למינימום האפשרי\” הוא דוגמה לשם נכון, שאינו מדויק (או בעל-משמעות). נתת לי הזדמנות לחזור לפוסט ולנסות לשפר אותו. תודה.ליאור