מתכנתים טובים כותבים קוד משעמם.
מתכנתים מעולים כותבים קוד ממש משעמם.
כשנתקלתי בציטוט הזה באינטרנט, אי שם, הוא הכניס אותי לחקור ולהבין את עולמות הקוד הנקי (כאשר במהלך המאמר נקרא להם בשמם המוכר – Clean Code).
תוכן עניינים
מה זה בכלל Clean Code?
במילים פשוטות Clean Code מתייחס לקוד שקל לקרוא ולהבין. כמה מאפיינים בולטים של Clean Code הם:
- מפחית עומס קוגניטיבי של מי שקורא את הקוד אחרינו.
- מכיל משתנים ופונקציות בעלי שם מובן ואינטואיטיבי.
- פועל לפי השיטות המומלצות לקידוד.
הקוד שלי כבר עובד טוב, למה צריך את זה?
טוב ששאלתם. הרבה מפתחים עשויים לחשוב, “הקוד שלי עובד טוב והלקוח שלי מרוצה, אז למה שיהיה אכפת לי לכתוב קוד נקי?”
גם אם הקוד שלכם עובד עכשיו, אתם צריך לחשוב את העתיד. אם הקוד לא נקי מלכתחילה, יהיה הרבה יותר קשה לתחזק, לעדכן או להרחיב אותו בעתיד.
Clean Code לא עוסק בכתיבת קוד שעובד, אלא שם דגש על קוד שקל לקרוא ולתחזק אותו בטווח הארוך. כפי שניתן לראות מהגרף הזה, העלות של תחזוקת קוד מלוכלך עולה לא מעט והבעיה גודלת באופן דרסטי עם הזמן, בעוד שבמקרה של כתיבת Clean Code, היא נשארת די קבועה וחוסכת לא מעט עלויות.
Clean Code הוא לא הפתרון המהיר ביותר או בהכרח המתוחכם ביותר מבחינת נראות, אבל כן יוצר קוד אלגנטי, כזה שאלה שינסו להבין אותו בעתיד יעשו זאת במאמץ מינימלי.
כשאתם כותבים קוד אתם צריכים להיות מודעים לסגנון שבו אתם כותבים את הקוד שלכם. תכנות הוא אמנות באותה מידה שהוא מדע. הנה כמה טיפים שיעזרו לך לכתוב Clean Code:
1. הימנעו מקינון מיותר
קינון בקוד הוא משהו שאנחנו עושים כל הזמן, ולמרות שאין שום דבר רע מטבעו בקינון, לפעמים זה יכול להקשות על קריאת הקוד. גישה אחת לעזור להימנע מכך היא להשתמש בתבנית העיצוב “החזר מוקדם”. זה מאפשר לנו להשתמש במשפט if כסעיף שמירה כדי לבדוק שגיאות ולהחזיר לפני ביצוע קוד נוסף. זה עוזר להימנע משימוש בif אחר וגם קינון מיותר כפי שתכף תראו.
לפני:
private static void DeleteItem(Item item)
{
if (item != null)
{
Console.WriteLine("Saving item");
item.Save();
}
}
אחרי:
private static void DeleteItem(Item item)
{
if (item == null) return; // or throw new ArgumentNullException();
Console.WriteLine($"Saving item: {item}");
item.Save();
}
חשוב להדגיש ששני קטעי הקוד מתנהגים באופן זהה, אך כפי שניתן לראות קטע הקוד השני הוא כמובן הנקי יותר. עכשיו בואו נסתכל על דוגמה של משפט if שהוא מקונן
לפני:
private static void SaveItemBad(Item item)
{
if (item != null)
{
Console.WriteLine("Validating");
if (item.IsValid)
{
Console.WriteLine("Saving item");
item.Save();
}
}
}
אחרי:
private static void SaveItem(Item item)
{
if (item == null) return; // or throw new ArgumentNullException();
Console.WriteLine($"Validating");
if (!item.IsValid) return; // or throw
Console.WriteLine($"Saving item: {item}");
item.Save();
}
זו טכניקה פשוטה שקל ליישם אותה. על ידי גישה קצת אחרת אנו יכולים באותו מאמץ ליצור קוד ללא קינונים בכלל.
כפי שאתם יכול לראות, גישת “החזר מוקדם” יכולה לעזור להפוך את הקוד שלך לליניארי נקי יותר ומובן יותר.
2. פונקציות קצרות שעושות פעולה אחת בלבד
יש הרבה חוכמה בהתעקשות על פונקציות פשוטות. כשאתה שומר על הפונקציות שלך קטנות וממוקדות, קל יותר להבין מה הן עושות ואיך הן עובדות. זה הופך אותם לפחות מועדים לטעויות וניתנים לתחזוקה. בנוסף, כאשר אתה שומר על הקוד מודולרי, קל יותר לעשות שימוש חוזר בפונקציות בודדות בהקשרים שונים בהמשך.
public void SignUpAndValidate()
{
// multiple operations logic
}
יותר נכון יהיה לחלק את הפונקציה לשתי פונקציות שכל אחת מהן תעשה פעולה אחת בלבד.
public void SignUp()
{
// one operation only
}
public void Validate()
{
//one operation only
}
3. שמות משתנים אינטואיטיביים
שמות נמצאים בכל מקום: פונקציות, מחלקות, קבצים וכו’ והם הבסיס לכתיבת קוד בכלל וקוד נקי בפרט. שם טוב הוא שם שיודע לספר את כוונת המשורר (או המתכנת במקרה שלכם).
//bad
var x = n.filter(e => e > 0);
//good
var positiveElements = numbers.filter(num => num > 0);
כפי שאתם יכולים לראות, הדוגמה השנייה הרבה יותר קלה להבנה מהראשונה.
במקרה של פונקציות – היכנסו למיינדסט שפונקציה היא פעולה, אז כשנחשוב על שם נחשוב על פעולה ולא על תיאור של הפונקציה.
// bad
function passwordValidation() {
}
// good
function validatePassword() {
}
במקרה של בוליאנים שם המשתנה צריך להיות בצורה של שאלה שניתן לענות עליה בכן או לא, כגון:
const isValid = false;
const hasAuthorization = true;
4. עקרון הDRY
העקרון אומר: אל תחזרו על עצמכם! (DRY = Don’t Repeat Yourself)
זה אחד הדברים הבסיסיים שצריכים להיות בכתיבת קוד נכון. זה משהו שאתם לגמרי יודעים לשים אליו לב תוך כדי תנועה – תשאלו את עצמכם: האם אני עושה קוד דומה ב-8 מקומות שונים? אם התשובה היא כן, אני חייב לחשוב איך להפוך את זה לפונקציה.
הימנעו מלעשות העתק הדבק לפיסות קוד, אם צריך מעבירים את הקוד לתיקיה / ספריה משותפת שנמשוך ממנה את הקוד המשותף לאיזורים הרלוונטים.
5. צמצם את מספר ההערות
ישנם כמה מקרים נדירים שבהם ייתכן שתזדקק להערות בעיקר במקרים בהם לא הייתה ברירה אלא לכתוב קוד לא אינטואיטיבי.
דוגמא (מוקצנת קצת אמנם) שתמחיש את מה שאני מדבר עליו:
// stop application services
stopServices()
לסיכום
חשוב לי להדגיש שמדובר בכמה טיפים ולא מעבר, יש עוד לא מעט עקרונות וטיפים שלא כתובים כאן, למי שרוצה להעמיק ממליץ לכם לקרוא את הספר של Uncle Bob או לחפש עוד מידע ברחבי הרשת.
עוד טיפ אחד אחרון לסיום – תדאגו שיהיה לכם תוסף לIDE שלכם שידע לזהות בזמן אמת טעויות בכתיבת קוד, Resharper הוא המומלץ עבור #C, עבור JS יש את Prettier, עבור Python אני מכיר את Black אך כמובן שיש לכל שפה את הכלי המומלץ שלו.
אחלה כתבה מעניינת וחשובה