קוד ספרותי = סופן של ההערות בקוד?

האם כתיבת הערות משמעותו קוד טוב יותר, או שהקוד הספרותי יכול להביא לסופן של ההערות הטורדניות, ועדיין לאפשר למפתחים להבין מה בדיוק כתוב בו ולמה הוא נועד?

מקור: Shutterstock

מקור: Shutterstock

כ-70 אחוזים מעבודת הפיתוח היא תחזוקה של קוד קיים – ולא כתיבה של קוד חדש. התחזוקה דורשת קריאה רבה של קוד קיים. בעצם, גם כתיבה של קוד חדש דורשת קריאה של קוד קיים: תוך כדי כתיבה אנו קוראים שוב ושוב. המסקנה: יש יתרון משמעותי בכך שקוד יהיה קל לקריאה.

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

מקור: ליאור בר-און

מקור: ליאור בר-און

טרמינולוגיה: קצת סדר

לאידאל של קוד אסתטי, אלגנטי וקל לקריאה נוהגים לקרוא בימנו “Clean Code” או “קוד נקי”. קוד נקי מורכב מ-2 אלמנטים עיקריים – מבנה הקוד (למשל: כל פונקציה עושה רק דבר אחד) וקוד ספרותי (“קל לקרוא את הקוד כמו ספר קריאה”).

בפוסט זה אני רוצה להתמקד ב”קוד הספרותי” (לא לבלבל עם Literate Programming – דבר אחר לגמרי) בלבד. לא בגלל שמבנה הוא פחות חשוב, אלא כי אחרת לא אסיים את הפוסט. גם בתוך הקוד הספרותי יש 2 אלמנטים מרכזיים: שפה טבעית (מונח שהמצאתי הרגע) ותיעוד עצמי (Self Documentation).

כלומר: רק כאשר יהיה לנו קוד החותר לשפה טבעית וגם “תיעוד עצמי” – נגיע לקוד הספרותי עליו אנו מדברים. כמובן שקוד קריא באמת (“Clean Code”) יהיה רק כאשר גם המבנה יהיה “נקי”. גישת הקוד הספרותי היא נפוצה – אם כי איננה קונצנזוס. היא התבססה בעיקר בעקבות 3 ספרים “פורצי-דרך”:

מכתב בשפת Ruby. מקור: Jacques Fuentes.

מכתב בשפת Ruby. מקור: Jacques Fuentes.

מהו “קוד ספרותי”?

הרעיון של קוד ספרותי מבוסס על 2 הנחות:

  1. קוד נקרא הרבה יותר פעמים מאשר הוא נכתב – ועל כן השקעה בקוד כדי שיהיה קריא, היא משתלמת.
  2. הערות הן משהו שאנו נוטים (באופן לא מודע, אולי) להתעלם ממנו. אנו יודעים שזה לא העיקר.

הערות יוצאות לאורך הזמן מסנכרון עם הקוד. הקוד הוא האמת – וההערות נשארות צל של העבר.

אנו מסוגלים לקרוא קוד תוך התעלמות מההערות, להבין את הקוד בצורה שגויה ולהמשיך הלאה.

אם הנחות אלו לא נכונות עבורכם – ייתכן וכל הגישה אינה מתאימה לכם. קוד ספרותי מבוסס על שני עקרונות:

עיקרון א’: שאיפה לשפה טבעית

על הקוד להיות קל לקריאה כמו ספר. השפה אליה אנו שואפים היא אנגלית ולא שפת-מחשב, כך שכל statement צריך לשאוף להיות משפט ברור באנגלית – ולא “קוד סתרים”. האמת ש”קוד ספרותי” הוא שם לא-מדויק, אולי אף מעט מטעה: סיפור של שייקספיר (מתפלפל) או של ג’ורג .ר.ר מרטין (לא-נגמר) – הם לא המודלים אליהם אנו שואפים. המודל מדויק יותר יהיה עיתון / “קוד עיתונאי”:

  1. תמציתי.
  2. ברור וחד-משמעי.
  3. מדויק.
  4. קל לקרוא קטעים ממנו.

ניתן לקפוץ לעמוד 6′ לקרוא פסקה ולהבין – מבלי שקראנו את כל העיתון. זאת בכדי שנוכל להתמקד בקטעי קוד שמעניינים אותנו כרגע, מבלי שנזדקק לקרוא מאות שורות של קוד קודם לכן בכדי להבין את הקטע המעניין.

עיקרון ב’: תיעוד עצמי (Self-Documentation)

על הקוד לתאר את עצמו ולהבליט את הכוונה. כל פעם שאנו מוסיפים הערה – זו נורת אזהרה שכתבנו קוד שלא מסביר את עצמו. עלינו לנסות להסיר את ההערה ולגרום לקוד לבטא את המסר ללא עזרה.

ייתכן ובשלב זה נראה לכם שנכנסנו לדיון פילוסופי-תאורטי. זה לא המצב. מיד נראה דוגמאות קוד.

אז כיצד כותבים קוד “ספרותי”?

נתחיל בחתירה ל”שפה טבעית”. הנה מספר עקרונות שננסה להדגים:

  1. שמות (משתנים, פונקציות, מחלקות) ברורים בשפה האנגלית.
  2. שמות המתארים “מה” ולא “כיצד”. למשל: Parser ולא LineScanner.
  3. שמירה על רצף קריאה קולח, ללא צורך לחזור לאחור או לדלג לפנים בקוד בכדי לקבל את ההקשר.

נתחיל במתן שמות:

// bad
var ic; // says nothing
function monitorTransIP() // what is IP?!
var hashUrl = "ae4a0192#erlkde"; // url of a Hash?
// good
int itemCount;
function monitorInProcessTransactions() // proper English
var urlHash = "ae4a0192#erlkde"; // no. a Hash of a URL...


כפי ששמתם לב, על השמות להיות באנגלית ולסייע להרכיב קוד שנראה ככל האפשר כמשפט באנגלית. כמובן שגם Camel Case הוא חשוב. נסו לקרוא שמות כמו mONITORiNpROCESStRANSACTIONS. לא מצליחים, נכון?

לא קל לקלוע ישר לשמות מוצלחים. ישנן 4 “דרגות” של שם:

  1. שם סתמי – המחשה: NetworkManager
  2. שם נכון – המחשה: AgentCommunicationManager
  3. שם מדויק – המחשה: AgentUdpPacketTracker
  4. שם בעל משמעות (“meaningful”) – המחשה: AgentHealthCheckMonitor*

* כמובן שהשם AgentHealthCheckMonitor הוא מוצלח רק במערכת בה שם זה מתאר בדיוק וביתר משמעות את אחריות המחלקה. נתתי דוגמאות להמחשה ממערכת שאני מכיר וחושב עליה – כמובן השמות שציינתי לא נכונים / מדויקים / בעלי משמעות באופן אוניברסלי, אלא רק למערכת הספציפית.

עצלנות ולחץ גורמים לנו להיצמד לתחתית הסקלה (1,2), בעוד הקפדה ומקצועיות דוחפים אותנו לראש הסקלה (3,4).

טריק מומלץ הוא לתת לפונקציה / משתנה חדש את השם “foo”, מבלי לחשוב. תוך כדי עבודה אתם מבינים מה הפונקציה עושה ומשנים את שמה. לאחר 10 דקות עבודה ייתכן והשם שונה כבר שלוש או ארבע פעמים, אך יהיה ניתן לראות עליות בדרגה של השם. לעתים פשוט צריך לנסות איזה שם ו”לחיות” אתו כמה דקות על מנת למצוא שם מוצלח יותר.

מתי מותר להשתמש בקיצורים?

קשה לטעון שהקוד הבא הוא לא קריא:

for (int i = 0; i < ObjList.length; i++){
    // doSomething
}

אף על פי ש-i ואפילו objList הם לא שמות ברורים באנגלית.

מדוע אם כן אנו מצליחים לקרוא את הקוד? א. יש בו קונבנציה מאוד ברורה. ב. אנו רואים במבט אחד את אורך החיים של i וכך מבינים בדיוק מה הוא עושה.

הכלל אם כן אומר: ככל ש-scope החיים של המשתנה הוא מקומי וקטן יותר – ניתן לקצר בשם. ככל ש-scope החיים של המשתנה הוא גדול יותר (למשל: קבוע ממחלקה אחרת) – יש להאריך בשם.

דוגמה:

// bad
for (int iterationIndex = 0; iterationIndex < l.length; iterationIndex ++){ 
    // doSomething(l[iterationIndex]) - what is "l" ?!?!
}
// good
for (int i = 0; i < completedTaskList.length; i++){
    // doSomething(completedTaskList[i])
}
// better?
completedTaskList.forEach(function(task){
    // doSomething(task)
});

הדוגמה אחרונה אכן מקרבת אותנו לשפה טבעית (“forEach”) וגם מקצרת את הקוד, אולם יש בה גם נקודה חלשה: היא שברה במעט את רצף הקריאה. באנגלית אנו נוהגים לומר: “…for each completed task” בעוד דוגמת הקוד דומה יותר ל “…with completed tasks, for each” (סוג של: “אבא שלי, אחותו …” במקום “אחות של אבי”) – שפה קצת מקורטעת.

ספציפית בג’אווהסקריפט יש תחביר של for… in ששומר אפילו טוב יותר על רצף הקריאה, אבל מציג כמה pitfalls משמעותיים – ולכן אני נמנע ממנו. בסופו של דבר אנו מוגבלים לאופציות הקיימות בשפת התכנות, ועלינו להחליט איזו אופציה אנו מעדיפים. כדאי לשקלל את כל המרכיבים לפני שבוחרים.

בדוגמה הנ”ל אני מעדיף את האופציה האחרונה שהיא קצרה, מקובלת, ובעלת “שפה טבעית”. נכון: היא לא מושלמת.

ג'ורג' אורוול. סופר ועיתונאי.

ג’ורג’ אורוול. סופר ועיתונאי.

שמירה על רצף קריאה

הנה כמה דוגמאות כיצד ניתן לחזק את רצף הקריאה:

// not very good
if (node.children() && node.connected()) {
  // doSomething
}

// better
if (node.hasChildren() && node.isConnected()) {
  // doSomething
}

נכון, Hungarian Notations היא סגנון שעבר זמנו, אבל ספציפית הקידומות has ו is מסייעות מאוד לקרוא את המשפט כאשר חסר לנו מספק פיסוק חשוב: סימן השאלה. בנוסף, הקוד שנוצר הוא קרוב יותר לאנגלית נכונה.

בשפת Java, מקובל לכתוב:

if ("someValue".equals(myString)) { ... }

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

if (myString.equals("someValue")) { ... }
עומס טקסט כמובן גם משפיע לרעה על קלות הקריאה, והייתי שמח הרבה יותר לכתוב:
if (myString == 'someVale') { ... }

באופן דומה, עבור הקורא:

if (myString.isEmpty()) { ... }

יותר קולח מקריאה של

if (myString.equals("")) { ... }
למרות שהתבנית מאוד מוכרת.

הנה עוד דוגמה קטנה לכתיבה מעט שונה, אך קולחת יותר:

// switch => reader has to remember 'statusCode' = the context
switch (statusCode) {
  case 169 : // return Something();
  case 201 : // return Something();
  case 307 : // return Something();
  default: // return SomeOtherStuff();
}

// Better: each line is a complete sentence 
switch (true) {
  case statusCode == 169 : // return Something();
  case statusCode == 201 : // return Something();
  case statusCode == 307 : // return Something();
  default: // return SomeOtherStuff();
}

במקום שהעין תקפוץ כל הזמן ל-statusCode להיזכר בהקשר (בדומה למשפטי “with”), כל משפט הופך למשפט שלם. כל זאת – בעזרת אותו סט כלים זמין בשפה.

בסופו של דבר, חשוב שתקשיבו כיצד אתם מסבירים לאחרים את הקוד שלכם. נסו לחתור לכך שהקוד ייקרא בדיוק כפי שהסברתם: מילה במילה (עד כמה שאפשר / סביר).

“תיעוד עצמי” – סיפורו של מתכנת

בכדי ללמוד כיצד נראה תיעוד-עצמי, בואו נפתח בסיפורו של מתכנת הלומד את רעיונות הקוד הספרותי, והקשר בין כמות ההערות שהוא כותב – להתמחות שהוא צובר:

מקור: ליאור בר-און

מקור: ליאור בר-און

כשהמתכנת חדש, הוא אינו כותב הערות. הוא עסוק בלגרום לקוד בכלל לעבוד (A).

עם הזמן, המתכנת מבין שיש חיסרון בקוד מבולגן ובלתי-קריא. הוא מתעד ומסביר עוד ועוד מה הקוד עושה. לעתים כל שורת קוד מקבלת הערה – בכדי שהכל יהיה “ברור” (B). לאחר זמן נוסף, המתכנת מקבל אמון בכתיבת הקוד שלו. תבניות מסוימות בקוד “מדברות בעד עצמן” והוא לא זקוק לתיעוד. הוא נחשף לרעיונות של “קוד ספרותי” ומגלה כיצד ניתן לתעד את הקוד ללא הערות. זה עובד, הוא מתלהב ועכשיו יש לו “משחק חדש” – לנסות ולחתור ל “0 הערות בקוד”, תוך כדי שהוא משאיר את הקוד קריא למדי.

הוא מפצח מקרה אחר מקרה (C) – ומצליח לכתוב קוד קריא ללא הערות, עד אשר הוא מגיע למצב בו הוא כותב קוד באורך אלפי שורות קוד ללא שורת הערה אחת.

זה אתגר, זה מהנה וזה עובד. הוא משתמש בטכניקות שוב ושוב ומצליח ליצור קוד קריא ללא הערות. הוא מביט בקוד שלו בהנאה – ומתמוגג. “הצלחתי” (D).

אבל, עוברים כמה חודשים והוא מקבל פרספקטיבה רחבה יותר. הוא מבין שיש דברים שלא ניתן לתעד בקוד בלבד. דוגמה פשוטה: קוד מדבר על “כאן ועכשיו”. איך הוא יספר למתכנת שיקרא את הקוד שלו שהוא עושה כאן “פעולה א” בגלל שמודול אחר מתנהג בצורה “ב”? שפונקציה זו היא בגלל בעיה היסטורית שהתרחשה בעבר? שפה עשו משהו זריז – אבל יש כוונה לשפר את זה בעתיד?

הוא גם שם לב שלמרות שאפשר לכתוב כל הערה מתוך הקוד – לעתים פשוט יותר לכתוב הערה. כאשר יש מעט הערות בקוד, וכל הערה היא חשובה – נוהגים לקרוא את ההערות יותר ולהתייחס אליהן ביתר רצינות. המתכנת חוזר לכתוב מעט הערות ובמשך הזמן מוצא את נקודת האיזון בין “קוד ללא הערות” ל “הערות שלא משתלם לבטא כקוד” (E).

העברת הערות לקוד

“כאן צריך הערה” הוא הקול הפנימי שבפסקה הבאה ננסה להתנגד לו. כל הערה היא סימן מובהק לקוד לא-קריא-מספיק. האם אנו רוצים לשים עוד פלסטר או לטפל בבעיה מהיסוד? בואו ננסה. ראשית ננסה להיפטר מ”מספר קסם” (Magic Number). מספר קסם הוא מספר שפתאום מופיע בקוד ולא ברור כיצד החליטו עליו. קסם.

/*= Huh?! =*/
totalHeight = $el.height + 14;

/*= Better =*/
totalHeight = $el.height + 6+6+1+1;

/*= Even Better =*/
// two times the border (6) + two times the margin (1)
totalHeight = $el.height + 6+6+1+1;

/*= Introduce constant; Even Better =*/
var BORDER_WIDTH = 6, MARGIN = 1;
totalHeight = $el.height + 2 * BORDER_WIDTH + 2 * MARGIN;

הערה: השתמשתי בהערות מסוג /*= =*/ כמטה-הערות בהן אני משתמש להעיר על הקוד / ההערות.

“14” הוא מספר קסם – לא ברור כיצד הגיעו אליו. פירוק לנוסחה (6+6+1+1) משפר את המצב, ובעזרת הערה – המצב אפילו טוב יותר. אבל, ההערה יכולה לצאת מסינכרון עם הקוד ולהפוך ללא-מעודכנת. לבסוף אנו כותבים את ההסבר בעזרת קוד בלבד – כזה שקשה יותר להתעלם ממנו או להשאיר אותו לא מעודכן. מצוין. בואו נראה דוגמה נוספת:

/*= Why do we need this comment ? =*/
// remove "http://" from the url
str = url.slice(7);

/*= Introduce constant; Slightly better =*/
var HTTP_PREFIX_LENGTH = 7;
str = url.slice(HTTP_PREFIX_LENGTH);

/*= comment -> code; Better =*/
str = url.slice('http://'.length);

הצלחנו לבטל את ההערה, ולהפוך אותה לחלק מהקוד – קוד קריא. נהדר.

פירוק של ביטויים לא ברורים לאיבר נוסף עם שם ברור אינה שמורה רק למשתנים. הנה טיפול ב”ביטוי קסם”:

/*= Why do we need this comment ? =*/
// check if document is valid
if ((aDocument.isAtEndOfStream() && !aDocument.hasInputErrors()) &&
    (MIN_LINES <= lineCount && lineCount <= MAX_LINES)) {
    print(aDocument);
}

/*= extract method; comment -> code =*/
if (isDocumentValid(docStream, lineCount)) {
    print(aDocument);
}

הוצאנו (extract) פונקציה, נתנו לה שם ברור – וביטלנו את הצורך בהערה!עד כאן טוב ויפה. יש מקרים שבהם נדמה לרגע שאין לנו דרך סבירה לבטל את ההערות, שהן פשוט נדרשות:

/*= We need these comments to highlight sections, don't we? =*/
function foo(ObjList){
    var result = [], i;

    // first fill objects
    for (i = 0; i < Objlist.length; i++){
        // doSomething
    }

    // then filter disabled items
    for (i = 0; i < result.length; i++){
        // doSomething
    }

    // sort by priority
    result.sort(function(a, b) {
        // apply some rule
    });

    return result;
}

/*= Extract Methods; comments -> code =*/
function foo(ObjList){
    var result = [];

    result = fillObjects(Objlist);
    result = filterDisabledItems(result);
    result = sortByPriority(result);

    return result;
}

כשאנו רואים פונקציה (foo) שמחולקת בעזרת הערות (כגון “first fill objects”) למקטעים, זהו רמז טוב שהפונקציה עושה יותר מדבר אחד. הפתרון העדיף הוא לחלק את הפונקציה למספר פונקציות, שכל אחת עושה פעולה אחת ויש לה שם ברור שמתאר מה היא עושה.

נכון, התוצאה היא יותר פונקציות קטנות וממוקדות – שזה בד”כ יתרון נוסף. אם המחלקה שלכם כוללת יותר מדי פונקציות קטנות – זהו סימן בד”כ שאפשר לפצל את המחלקה לכמה מחלקות

האם גם בדוגמה הבאה ניתן לוותר על ההערה?

function calcRevenue(){<
    /*= Walla! This comment is Absolutely Irreplaceable! =*/

    // Order Matters!
    calcMonthlyRevenue();
    calcQuartrlyRevenue();
    calcAnnualRevenue();
}

function calcRevenue(){
    /*= Hmmm... better luck next time =*/

    var lastMonthRevenue = calcMonthlyRevenue();
    var lastQuarterRevenue = calcQuartrlyRevenue(lastMonthRevenue);
    calcAnnualRevenue(lastQuarterRevenue);
}

במקרה זה הייתה לנו הערת “meta” על הקוד: “סדר השורות חשוב!” – הערה שנראה במבט ראשון שאין לה תחליף. ביטלנו את ההערה ע”י יצירת קשר הכרחי (אם כי מעט מלאכותי) בין הפונקציות המתאר בדיוק את הקשר.

דוגמה זו היא מעט קיצונית ויכולה להיכשל בקרב מפתחים שלא מכירים את ה convention של “תלות מפורשת בין פונקציות”. מצד שני, יצא לי להיתקל בהערת “Oder Matters” שהתעלמו ממנה ויצרו באג – כך שאני לא בטוח מה עדיף.אני מניח שבשלב זה הרעיון כבר ברור. הייתי רוצה לקנח בדוגמה לא מפתיעה, אך חשובה: מבני נתונים

/*= Custom data structure: working, but not descriptive =*/
var row = new Array[2]; // team's performance
row[0] = "Liverpool";
row[1] = "15";

/*= Comments -> code; but what are 0 & 1? =*/
var teamPerformance = new Array[2];
teamPerformance[0] = "Liverpool";
teamPerformance[1] = "15";

/*= Introduce Class =*/
var tp = new TeamPerformance();
tp.name = "Liverpool";
tp.wins = "15";

ביקורת

ישנן גם התנגדויות לגישת “הקוד הספרותי”. הנה ביקורת מפורסמת (וצבעונית) שהתפרסמה. הנה התגובה של דוד בוב.

אקצר לכם 10 דקות של וידאו (אם הנושא מעניין אתכם – הייתי משקיע את הזמן): לביקורת, למרות צבעוניותה, יש נקודה: כתיבת קוד ספרותי גורמת לנו לבצע Refactor מסוג Extract הרבה פעמים – מה שיוצר יותר פונקציות קטנות ופחות רצף קריאה של קוד. דוד בוב עונה: פונקציות קטנות מבטיחות קוד “עיתונאי” בו אפשר להביט בנקודה x מבלי לקרוא הרבה שורות קוד קודמות בכדי להבין את הקונטקסט.

בסופו של דבר חשוב להבין ש”קוד ספרותי” הוא כלי. יש להשתמש בו בתבונה ובמידה. “קוד ספרותי” דורש עוד עבודה. “קוד ספרותי” דורש מיומנות נרכשת. “קוד ספרותי” לא גורם ללקוחות לשלם יותר. אבל אם הקוד שלנו הוא קוד “חי” שעובר הרבה שינויים ותחזוקה – קוד ספרותי יכול להיות מאוד משתלם לאורך זמן.

סיכום

ראינו כיצד ניתן לשפר את הקריאות שלנו ולאו דווקא בעזרת הערות. בעזרת כתיבת קוד שדומה לשפה הטבעית (במקרה זה: אנגלית) הן ברמת התחביר והן ברמת השמות. ראינו שהשמות לא משנים אולי כ”כ ל-Compiler, אבל הם משנים הרבה מאוד לבני-אנוש שקוראים את הקוד. לא קל להגיע מיד לשמות מוצלחים, זו עבודה ומיומנות.

ראינו כיצד אפשר לכתוב קוד המבטא את המסר גם ללא עזרה מאותן “הערות נלוות”. כתיבת הערה צריכה להדליק לנו נורת אזהרה: “כאן נכתב קוד לא-מספיק-ברור”, כזה שמחייב תלאי בדמות הערה בכדי להסביר מה עשינו.

כמובן שיש פעמים בהן נרצה הערות. קוד מתאר “כאן ועכשיו” ולא יכול לבטא כוונות או היסטוריה. לעתים, ניתן לבטא כוונה בעזרת קוד בלבד – אך התוצאה היא מסורבלת ואנו נעדיף הערות. בונוס: כשיש מעט הערות בקוד – קוראים אותן יותר וביתר תשומת-לב.

למדנו ש”קוד ספרותי” הוא רק אבן-דרך אחת בדרך ל”קוד נקי”. מבנה התכנית חשוב לא פחות. לעתים קרובות יש לנו אלגוריתם או flow מסובכים / לא-ברורים. כתיבת קוד “ספרותי” תעזור רק במעט, בעוד הפתרון האמיתי הוא להכין לעצמנו כוס גדולה של קפה ולשבת על הקוד עד אשר נבין מדוע הוא מסובך – וכיצד אפשר לפשט אותו. שיפור מבנה הקוד הוא לא משהו שכיסינו בפוסט זה.

בנוסף ל”קוד ספרותי” ו”מבנה” יש אלמנטים נוספים המשפיעים על קריאות הקוד, כגון “אסתטיקה של קוד” (ריווחים, עימוד וכו’) ואחידות הקוד. באחידות של קוד יש לשמור על האיזון בין שימור האחידות הקיימת לחידוש. עם הזמן נפתח סגנון טוב ומתקדם יותר – וכדאי למצוא את הדרך להתחיל ליישם אותו ולא רק “להיתקע עם הסגנון הישן”.

איך מתחילים לכתוב “קוד ספרותי”? הכי פשוט להיצמד לכלל הצופים (The Boy Scout Rule): “השאר את השטח נקי יותר ממה שקיבלת אותו”. כל פעם שאתם נוגעים בקוד ומבצעים שינוי – שפרו מעט את הקריאות וקדמו מעט את הקוד לעבר “קוד ספרותי”. עם הזמן – השינוי יהיה ניכר ויגיעו גם התוצאות.

שיהיה בהצלחה!

פורסם לראשונה בבלוג Software Archiblog.

מקור תמונה: Shutterstock.

ליאור בר-און

ליאור בר-און הוא Chief Architect בחברת סטארטאפ ישראלית גדולה.

הגב

16 תגובות על "קוד ספרותי = סופן של ההערות בקוד?"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.

סידור לפי:   חדש | ישן | הכי מדורגים
תחכמוני
Guest

בג’אווה היית שמח לכתוב

if (myString == ‘someVale’) { … }

אבל רוב הסיכויים שאתה רוצה להשוות את תוכן הסטרינג ולא את הפוינטרים אז אין לך כל כך ברירה

אלון
Guest

כתבה מעולה, תביאו עוד כאלה :)

דורון מועלם
Guest

תחכמוני כתב את מה שרציתי…
=)

חנית כהן
Member

מסכימה לחלוטין, שים לב שבספר C הבסיסי (והמקורי) של קניגהם וריצ’י משתמשים בדיוק בסגנון כזה.
למעשה דניס ריצ’י הוציא ספר בנושא בשנת 99 בשם The Practice of Programming

123
Guest

אולי זה בגלל שאני לא מתכנת JS, אבל כשראיתי את הדוגמא עם ה-
(switch (true
הייתי צריך כמה רגעים כדי להבין מה בדיוק קורה שם. בתור מתכנת ++C, ה-idiom הזה די מזעזע בעיני – הוא מחליף בין החלק הדינמי (הערך שבודקים) לחלק הסטטי (האפשרויות). אם הייתי רואה דבר כזה בקוד שאני עובד עליו, כנראה שהייתי מחליף אותו באפשרות המקובלת יותר (בעולם שמחוץ ל-JS, כנראה). הנקודה היא לא שהביטוי הספציפי הזה גרוע, אלא שקריאוּת היא גם עניין קצת סובייקטיבי. שימוש בתכונות “גנדרניות” של השפה יכול גם להוות בעיה מבחינת הבהירות של הקוד.

זוהר
Guest

“בתור מתכנת ++C, ה-idiom הזה די מזעזע בעיני ”
זה ממש לא, גם בתור מתכנת C++ הייתי משתמש בביטויים מהסוג הזה, אני לא הייתי
קושר את זה לשפה.

כשאתה מתכנת מתחיל אתה נצמד לסטנדרט, אבל עם הנסיון מתחילים להסתכל על
הקוד בצורה אחרת ומתחילים לכתוב בצורה גמישה יותר כך שהקוד יהיה קריא.

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

שי
Guest

זה לא יעבוד ב C כי הערכים חייבים להיות קבועים בזמן קומפילציה.

שי
Guest
לעולם לא קראתי מאמר שהסכמתי איתו פחות. אני באמת חושב שCLEAN CODE זאת דרך של מתכנתים יהירים לבצע אוננות עצמית מוגזמת. לתת שם יפה לחוסר מקצועיות ולרשלנות לא הופך את זה למקובל. שפת תכנות היא לא שפה של בני אדם (גם אם קוראים לה שפה), אנגלית היא שפה של בני אדם. בפרוייקט אמיתי ורחב היקף, כשיש לך 5 שפות תכנות מעורבות זו בזו, כדאי מאוד שתתעד כל שורה (!). מאוד אהבתי שההצדקות במאמר נובעות אך ורק מחוסר מקצועיות: “זה לוקח לי זמן לתעד”, “אם אני אתעד אני ארשה לעצמי לכתוב קוד גרוע יותר כי התיעוד יסביר אותו”, “אני גם ככה… Read more »
תחכמוני
Guest

האמת ,כרגיל, היא באמצע.
לא צריך לכתוב “קוד ספרותי” שמנסה להדמות לאנגלית, אבל גם בטח ובטח שלא לשים הערה על כל שורה.

רוב השורות, אם כתובות בהגיון, מסבירות את עצמן. במקומות טריקיים שלא כזה ברור מה נעשה, לשים הערות.

ראובן קרסיק
Guest

מאמר מדהים וחובה לכל מתכנת! תודה רבה!

גבי והחמוצים
Guest

כתבה נחמדה מאוד, עם דגשים מעשיים, אהבתי (אם כי לא עם הכל הסקמתי).

תודה.

שמוליק
Guest

פוסט מעולה!!

חבל שבאקדמיה לא לומדים את זה , שם מדרבנים לכתובת הערות יותר מקוד לעתים אפילו לא משנה מה תוכן ההערה העיקר שהיא שם.

בב
Guest

מאמר מצוין לטעמי.

רוני
Guest

מאמר מעולה. תודה, ליאור.
ממליץ לכל מי שאהב את המאמר לקרוא את Clean Code. ספר מעולה שמספר את הסיפור של מאמר זה בהרחבה, הוא קל לקריאה. עבורי הוא שינה את כל סגנון הקידוד שלי לחלוטין.

wpDiscuz

תגיות לכתבה: