סעיפי משמר + להכשל מהר

הפוסט של היום יעסוק ב-"סעיפי משמר", או באנגלית Guard Clauses.

מהם בעצם אותם "סעיפי משמר"?
כשאנחנו נכנסים לפונקציה ניתן לומר שבמרבית המקרים אנחנו נכנסים עם פרמטרים.
כדי לשמור על ודאות גבוהה ויציבות, כדאי להכשל מהר (Fail Fast) במידה והקלט שלנו לא תקין.
דבר זה מתבצע על ידי כתיבת מספר תנאי בסיס בכניסה לפונקציה וזריקת שגיאה מתאימה (האופציה המועדפת עליי היא ArgumentException ונגזרותיה).

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

למה להכשל מהר?
ראשית, אם אנחנו יודעים שיש איזושהי בעיה - למה לחכות? שוב דבר טוב לא יקרה אם נחכה.
שנית, שיקולי יישור (איידנטציה) - הקוד הרבה יותר קריא, הרבה יותר מסודר והרבה יותר ברור כשהוא מישורי ולא הררי מדי.

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

הנה דוגמה קטנה:



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

 תחליטו בעצמכם מה יותר נקי ;)

עידן

2 תגובות:

  1. הצגת את זה יפה וברור.
    אני חושבת שזה מימוש חלקי של הרעיון של design by contract
    רק לא מבינה/בטוחה לגבי הקשר ל"שיקולי יישור", נראה לי שיש מקום להסביר יותר.

    השבמחק
    תשובות
    1. כשאמרתי שיקולי יישור התכוונתי למה שיותר נכון לקרוא לו הזחה - המרחק של שורה מהשוליים השמאליים.

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

      אני לפחות מעדיף לפתוח בלוק כאשר התנאי שואל בצורה חיובית על לוגיקה שחשובה לאותה הפונקציה.

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

      מחק