מתי עוצרים?

בתיעוד של Redux מוצגת הדוגמה הבאה ל Reducer:

function counterReducer(state = { value: 0 }, action) {
  switch (action.type) {
    case 'counter/incremented':
      return { value: state.value + action.payload }
    case 'counter/decremented':
      return { value: state.value - action.payload }
    default:
      return state
  }
}

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

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

  2. אין טיפוסים - לא ברור מה צריך להיות הערך של action.payload ואיך הוא מחובר ל action.type בלי לקרוא ולהבין את הקוד עצמו.

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

אז אין ספק שעם 10 שורות הכל עובד מעולה אבל ב 500 שורות כבר אי אפשר לתחזק את הקוד. ועכשיו השאלה מתי עוצרים? מתי משכתבים את היסודות כי הלוגיקה של המערכת שלנו נהייתה מסובכת מדי? אני יכול לחשוב על 3 אפשרויות:

  1. אפשר לחפש מהתחלה בסיס שיגדל טוב - לדוגמה אפשר להתחיל את הפרויקט עם Redux Toolkit ו TypeScript ולקבל יסודות טובים יותר מהשניה הראשונה.

  2. אפשר לזהות שקטעי קוד מסוימים "מתחילים" להיות מכוערים או קשים לתחזוקה ולשכתב את היסודות איפשהו סביב הנקודה הזאת.

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

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