אני מניח שכולכם מכירים את המונח "חוב טכני" (Technical Debt), מונח שקבע Ward Cunningham בכדי לעזור ולחשוב על פשרות טכניות במערכת - שיש להן השפעות ארוכות טווח.
משמעות "חוב טכני" היא שפיתחנו פיצ'ר מסוים, וידענו שהפתרון הנכון ארכיטקטונית הוא פתרון X.
משיקולי זמנים (time-to-market, בעיקר), בחרנו ליישם פתרון נחות-ארכיטקטונית שנקרא לו x`.
את הפער בין הפתרון הרצוי ארכיטקטונית X לפתרון המצוי x` מתארים כחוב שיש להחזיר "למערכת". כמו חוב לבנק - הוא צובר "ריבית" בדמות פיתוח יקר יותר של הפיצ'רים הבאים, שייקח יותר זמן לפתח - בגלל קיצור הדרך שלקחנו.
למשל: בפיצר מסוים, במקום ליצור טבלה חדשה בבסיס הנתונים המתארת בצורה מדויקת את אופי האובייקט o, החלטנו "להלביש" את קיום האובייקט o על טבלה קיימת. שחררו את הפיצ'ר מהר יותר - אבל יצרנו עיוות שעכשיו בפיצ'רים חדשים נצטרך לעשות עבודה נוספת / לפתור חוסרי-התאמה חדשים בתוך המערכת, כי לא עשינו את ה"פתרון הנכון".
למטאפורה של "חוב טכני" יש כמה צדדים מדויקים יותר, ומדויקים פחות:
בואו ננסה לדייק כמה נקודות, מעבר להגדרה הפשוטה של חוב טכני:
חובות טכניים, הם לא אחידים, ולא כדאי להתייחס אליהם ככאלו. אם ניזכר לרגע בכמה חובות טכניים מפורסמים:
כפי שראינו, חובות טכניים הם שונים זה מזה - ולא נכון להתייחס אליהם כמקשה אחידה.
אני יכול לעסוק בהגדרות שונות ומשונות לחובות טכניים, וסיווגים שונים כיצד הם נוצרים.
זה לא מעניין מבחינתי.
בכל מערכת יש סדרה אינסופית (מבחינה מעשית) של חובות טכניים: כמה מהותיים, קצת יותר בינוניים, והמון פצפונים. ככל שנתקדם - ייווצרו עוד.
הניסיון "להחזיר את החוב עד תומו" - הוא נאיבי וחסר-בסיס.
הזדמן לי פעם לעבוד בארגון גדול שבו ניתנה הזדמנות נדירה להשקיע חצי שנה של כל גוף הפיתוח על מנת לנקות "חובות טכניים" ממוצר שלא היה חריג מבחינת החובות הטכניים שבו (אני יודע לומר בדיעבד).
תוך כדי פתרון חובות טכניים מסוימים - נוצרו גם אחרים.
בשום רגע, לא הייתה הסכמה מלאה מהו חוב טכני ומה לא. עשרה יהודים = מאה דעות.
זה היה פשוט תרגיל נפלא ביתירות הנדסית. לאחר חצי-שנה המוצר שוחרר לשוק - שם זכה לכישלון מסחרי נחרץ, והוא נסגר זמן קצר לאחר מכן.
את החובות הטכניים המשמעותיים - לא יגלו לכם כלי בדיקה אוטומטיים (כגון Static Analysis tools): הם יגדלו את הקטנים עד הפצפונים - והמון מהם, אך גם לא את כולם.
החובות הטכניים הגדולים הם דברים ש"עקומים" במערכת, בארכיטקטורה שלה, בתהליכים שלה, ובתיאור המציאות שלה. אנחנו נלמד עליהם ממי שמכיר היטב את המערכת ועובד איתה ביום-יום, אם כי לעתים זקוקים לעתים לנקודת מבט של מישהו שעדיין לא התרגל לרעות החולות - ויכול להצביע עליהן, ועל האפשרות לעשות את הדברים טוב יותר.
בחובות הטכניים הגדולים לא קשה כ"כ לשכנע את ההנהלה - כי אפשר להסביר להם מה עובד לא בסדר, ויש לכך לרוב כמה עדויות.
הרבה פעמים קשה לשכנע בקיום חוב טכני משמעותי לפני שהוא מתחיל לתת את אותותיו, והרבה יותר קל לשכנע אחרי שנזק הולך ונגרם. יש הוכחות.
בתפיסת ה Lean Architecture, חשוב מאוד להבין את הדינמיקה הזו.
כאשר אנו מזהים חוב טכני שהולך להיות מיושם, שווה לעשות מאמץ ולנסות למנוע אותו מבעוד-מועד.
לא תמיד נצליח לשכנע שזה אכן מדובר בחוב טכני משמעותי - לפעמים פשוט לא תהיה הסכמה על קיומו של החוב או משמעותו. בפעמים אחרות, תהיה הסכמה - אך עדיין החלטה לקחת אותו ולהתקדם הלאה.
גם במקרים כאלו, לא כדאי להתייאש או לריב עם כל הארגון, על מה שהארגון כרגע לא מסוגל לראות.
עומדים לרשותנו עדיין שני כלים:
בגדול, יש שלושה אלמנטים חשובים בטיפול בחוב טכני:
הציד הוא דליל רוב ימות השנה, וחשוב להתמודד עם המחסור.
אבל מידי פעם, יעבור באזור עדר גדול של בפאלו נודד. שבט שמתחיל לפעול רק כאשר העדר כבר הגיע - לא ישרוד לאורך זמן. עליו להיות מוכן ליום הזה, ולנצל את ההזדמנות ברגע שהגיעה - עד תום.
באופן דומה, הזדמנויות לצמצום החוב הטכני, לא נופלות מהשמיים, ולא כל ימות השנה. עליכם להיות מוכנים עם תוכנית אופרטיבית - שכאשר יש הזדמנות ("אוי - יש לנו מפתח פנוי בחודש הקרוב"), אנחנו יודעים בדיוק מה לעשות, יש לנו מגוון אפשרויות - ואנו יכולים להפיק מההזדמנות את המירב.
ניהול "רשימת בעיות":
גם כאשר הזמן המוקצה לצמצום חובות טכניים הוא "גלובאלי" (משותף לכל ארגון הפיתוח) - חשוב מאוד כיצד הוא מתוקשר ומנוהל.
רעיון אחד שנתקלתי בו הוא הרעיון שיתירות בפיתוח (כלומר: יש יותר מפתחים ממה שצריך) - יאפשר לטפל בחוב טכני בצורה טבעית. זה רעיון הגיוני לוגית - אך לא ראיתי אותו אף פעם קורה בפועל:
צוות לצמצום חובות טכניים:
בגלל שהבעיות לעתים דורשות השקעה ארוכה, ומומחיות - אחד המודלים הוא לייצר "צוות תשתיות" או צוות שיתקן בעיות במערכת.
למי שיש לו ניסיון בתוכנה, הרעיון הזה עשוי להישמע מופרך כמו הרעיון שעובדים outsource יבואו וינקו את הקוד (יבצעו refactoring) עבור המתכנתים של הארגון. אבל היי - גם דבר כזה קיים.
צמצום חוב טכני - כאירוע:
מודל אחר שיכול לעבוד הוא לרכז מאמץ של יחידה גדולה, או כל הפיתוח - על מנת לצמצם במרוכז חובות טכניים.
בכל מקרה, חשוב לתת את הבמה הראויה לתיקון של חובות טכניים משמעותיים - להלל ולהעריך בפומבי את מי שפתר בעיה מהותית. ההוקרה גם מצדיקה עבודה שהיא פעמים רבות קשה ומתישה, וגם משדרת בארגון שאנו מעריכים הנדסה טובה - ולא רק עמידה ביעדים ("בכל מחיר").
שוב אמרתי לעצמי, שאבחר נושא קצרצר לפוסט, ואכתוב משהו באורך 4 tweets לכל היותר. לא הצלחתי - היה לי יותר מה לומר משחשבתי.
כמה דגשים שחשוב לי שלא תצאו מקריאת הפוסט בלעדיהם:
משמעות "חוב טכני" היא שפיתחנו פיצ'ר מסוים, וידענו שהפתרון הנכון ארכיטקטונית הוא פתרון X.
משיקולי זמנים (time-to-market, בעיקר), בחרנו ליישם פתרון נחות-ארכיטקטונית שנקרא לו x`.
את הפער בין הפתרון הרצוי ארכיטקטונית X לפתרון המצוי x` מתארים כחוב שיש להחזיר "למערכת". כמו חוב לבנק - הוא צובר "ריבית" בדמות פיתוח יקר יותר של הפיצ'רים הבאים, שייקח יותר זמן לפתח - בגלל קיצור הדרך שלקחנו.
למשל: בפיצר מסוים, במקום ליצור טבלה חדשה בבסיס הנתונים המתארת בצורה מדויקת את אופי האובייקט o, החלטנו "להלביש" את קיום האובייקט o על טבלה קיימת. שחררו את הפיצ'ר מהר יותר - אבל יצרנו עיוות שעכשיו בפיצ'רים חדשים נצטרך לעשות עבודה נוספת / לפתור חוסרי-התאמה חדשים בתוך המערכת, כי לא עשינו את ה"פתרון הנכון".
למטאפורה של "חוב טכני" יש כמה צדדים מדויקים יותר, ומדויקים פחות:
- מתאר יפה את המצב:
- לחוב טכני יש "עלות" או "ריבית" שתכביד עלינו ונשלם עליה - עד אשר החוב יוחזר.
- בחוב טכני יש משהו גם חיובי: פעמים רבות נכון לביזנס לעשות פשרה מידית בכדי להשיג תוצאה מידית. הדבר טבעי במיוחד לשוק האמריקאי שם צמיחה של חברות היא מבוססת חובות - וזה מודל שמצליח.
- לא מתאר בצורה טובה:
- חוב כספי הוא מספרי וקל לחשב אותו: בדולרים. חוב טכני הוא לא מדויק, לא ניתן ממש להעריך את העלות "להחזיר אותו" וגם לא ניתן למדוד במדויק את הנזק שהוא גורם לאורך זמן.
פריון מפתחים - הוא נושא לא-מדויק מטבעו. - חוב כספי, גדול ככל שיהיה אפשר להחזיר ברגע אחד. חוב טכני משמעותי יוחזר על ידי עבודה ארוכה, של המשאבים הקיימים.
- יש כלים (למשל: SonarQube) שמנסים לתת מספר (זמן / דולרים) שיתאר את החוב הטכני של המערכת. קצרה היריעה מלפרט עד כמה ההערכות הללו הן סתמיות...
אין לי מטאפורה טובה יותר בכל מימד, אבל אולי מטאפורה של סמי-מרץ - היא מטאפורה משלימה למטאפורה של "חוב טכני".
- אם אנחנו ספורטאים, ואנחנו בתחרות - נסכים לעשות הרבה בכדי לעמוד יפה בתחרות.
- רופאים אומרים שהרבה קפה הוא דבר מזיק - אבל אני בטוח שיש כמה ספורטאים שהוא עוזר להם. אי אפשר לנבא ולמדוד את התוצאות השליליות - זה נושא מורכב ולא מדויק. הרבה ספורטאים הצליחו עם כמה התנהגויות שנחשבות לא בריאות (ספורט תחרותי, בכלל - הוא דבר לא בריא לגוף...) וחיו לאורך שנים.
- יש גם סמים קשים יותר, עם תמורה קצרת טווח חזקה יותר - אבל גם סיכון לנזקים חמורים בהרבה.
- במידה והחלטנו להפסיק להשתמש בסמי-מרץ קשים, תהליך השיקום עומד להיות ארוך וכואב - בדומה מאוד לחוב טכני עמוק ומשמעותי... זה לא נגמר ביום, אלא זה מסע מפרך וכואב שאי אפשר לדעת מתי יגמר.
קצת מעבר להגדרה היבשה
בואו ננסה לדייק כמה נקודות, מעבר להגדרה הפשוטה של חוב טכני:
- לא תמיד אנחנו צודקים בהערכה שארכיטקטורה X עדיפה על ארכיטקטורה x`.
- לעתים אנו מבצעים הערכות-יתר לחשיבות של אופן מימוש מסוים.
- לפעמים הנסיבות משתנות באופן בלתי-צפוי: דרישה או צורך באובייקט מרכזי במערכת מתבטל או משתנה, ופתאום x` הופכת לארכיטקטורה עדיפה על X. זה לא קורה כל יום, אבל זה קורה.
- גם כאשר ארכיטקטורה X עדיפה - לא תמיד היתרון שלה הוא משמעותי או מוצדק.
- יכול להיות ש"לתקן" את החוב הטכני יעלה יותר מכל מחיר שנשלם אי פעם בחיי המערכת, בשל העיוותים שיצר. דוגמה קלאסית: שמות של עמודת בבסיס הנתונים: השם הלא-נכון מציק, אבל שינוי עשוי להיות יקר מאוד לביצוע.
- הצהרה על חוב טכני הוא לעתים "קלף מיקוח" בניסיון להשפיע על אחרים בכדי להסכים דרך פעולה שאני רוצה לקדם. מתוך רצון להשפיע - אני עלול להגזים (ויותר) בתיאור החוב הטכני.
- "חוב טכני" הוא טיעון של אנשי-טכנולוגיה, לא אנשי ביזנס
- אחד מסוגי החובות הטכניים הנפוצים והמזיקים ביותר הוא הנדסת-יתר (over-engineering). הרבה יותר קשה להתקדם ולפתח פ'צרים עם 6 שכבות הפשטה - אם נדרשות רק 2.
- במקרים של הנדסת-יתר לרוב לא נשמע את הקול שאומר "זהו חוב טכני. אנחנו חייבים להחזיר אותו (להסיר רמות הפשטה) בכדי להתקדם יותר מהר", אבל הרבה פעמים - זה בדיוק המצב.
- וריאציה אחרת היא סיבוך המערכת ויצירת חוב-טכני, דווקא תחת ה ticket של "החזרת חוב טכני".
לא תמיד מתן אשראי למי שמוכן "להחזיר חוב טכני" - היא פעולה נכונה. עולם התוכנה הוא אכן מורכב: על מנת לפעול נכון חשוב לצלול ולהבין את הדברים. - למרות ערימת ההסתייגויות למעלה, חוב טכני עמוק הוא דבר הרסני למוצר ולחברה
- חובות טכניים עמוקים, בליבת המוצר והמודל שלו - עשויים לעשות את ההבדל בין מוצר מצליח לכושל.
חוב טכני - אבוי! מקור: וויקיפדיה |
חובות טכניים, הם לא אחידים, ולא כדאי להתייחס אליהם ככאלו. אם ניזכר לרגע בכמה חובות טכניים מפורסמים:
- באג 2000 (Y2K) - אבותינו חסכו בשטח האחסון ולכן מידלו שנה כ-2 ספרות ("95") ולא כ-4 ספרות ("1995"). מה קורה כאשר מגיעה שנת 2000? מיון? בדיקה איזה תאריך קדם לשני? - בלאגן.
החוב הטכני קיבל פרופיל תקשורתי עולמי - והיה סיכון ברור ומידי. למרות נבואות-זעם על עולם לא-מתפקד, הוא תוקן בזמן (ובמחיר עצום), ועברנו לשנות ה-2000 בשלום. - Referer של HTTP - בתקן ה HTTP הוגדר header חשוב בשם Referrer. בתקן נפלה שגיאת כתיב (נכתב: "Referer") אך עד שגילו את הטעות כבר היו עשרות מפתחים ואולי מאות מפתחים כבר מימשו את שגיאת הכתיב. מלבד בדיחה על בקשה שהוגשה למילון אוקסופרד לתקן את הטעות במילון (שם יותר קל לתקן) - לא נעשה ניסיון אמיתי לתקן את שגיאת הכתיב. זו דוגמה טובה לחוב טכני שהוא טעות - אך לא משתלם לתקן. ככל שהזמן עובר - זה הופך למשתלם אפילו פחות.
- דוגמה נוספת למשהו שאולי היה רצוי לתקן, אך בלתי-אפשרי בעליל הוא שיטת המדידה האימפריאלית הנהוגה בארה"ב. מדוע צריך לעבוד עם המרות לא נוחות כמו "מייל הוא 5280 רגל"? האם השיטה המטרית היא לא נוחה יותר? - כנראה שכן, אבל כבר מאוחר מדי.
- להתחיל מערכת חדשה ללא בדיקות-יחידה / CI-CD אמיתי / תשתית לוגים סבירה - היא דוגמה לחוב טכני הרסני. אלו דברים שאם לא מתחילים איתם, הקושי להוסיף אותם מאוחר יותר הוא חסר תקדים. הייתי שותף להשקעה של שנות-אדם רבות בניסיון להחיל בדיקות יחידה, CI אמיתי, או תשתיות לוגים במספר מערכות שונות ש"גררו כמה שנים בלי". על אף מאמצים הרואיים, מגובי-הנהלה גבוהה - לא זכיתי לחזות במקרה שהייתי מגדיר כמוצלח.
- רק להסיר ספק: קיום כל אחד מהשלושה הנ"ל הוא כלי productivity חשוב מאוד לארגון פיתוח / למערכת.
ה"טורנדו" של הסתבכות המערכת. למי שלא חווה - זו עשויה להראות כמו דאגה מופרזת, אך למי שחווה הגעה לאזור האדום או הסגול - זו חוויה מדכאת, שלא תרצו לחזור אליה... |
איך (לא) מחזירים חוב טכני?
כפי שראינו, חובות טכניים הם שונים זה מזה - ולא נכון להתייחס אליהם כמקשה אחידה.
אני יכול לעסוק בהגדרות שונות ומשונות לחובות טכניים, וסיווגים שונים כיצד הם נוצרים.
זה לא מעניין מבחינתי.
בכל מערכת יש סדרה אינסופית (מבחינה מעשית) של חובות טכניים: כמה מהותיים, קצת יותר בינוניים, והמון פצפונים. ככל שנתקדם - ייווצרו עוד.
הניסיון "להחזיר את החוב עד תומו" - הוא נאיבי וחסר-בסיס.
הזדמן לי פעם לעבוד בארגון גדול שבו ניתנה הזדמנות נדירה להשקיע חצי שנה של כל גוף הפיתוח על מנת לנקות "חובות טכניים" ממוצר שלא היה חריג מבחינת החובות הטכניים שבו (אני יודע לומר בדיעבד).
תוך כדי פתרון חובות טכניים מסוימים - נוצרו גם אחרים.
בשום רגע, לא הייתה הסכמה מלאה מהו חוב טכני ומה לא. עשרה יהודים = מאה דעות.
זה היה פשוט תרגיל נפלא ביתירות הנדסית. לאחר חצי-שנה המוצר שוחרר לשוק - שם זכה לכישלון מסחרי נחרץ, והוא נסגר זמן קצר לאחר מכן.
את החובות הטכניים המשמעותיים - לא יגלו לכם כלי בדיקה אוטומטיים (כגון Static Analysis tools): הם יגדלו את הקטנים עד הפצפונים - והמון מהם, אך גם לא את כולם.
החובות הטכניים הגדולים הם דברים ש"עקומים" במערכת, בארכיטקטורה שלה, בתהליכים שלה, ובתיאור המציאות שלה. אנחנו נלמד עליהם ממי שמכיר היטב את המערכת ועובד איתה ביום-יום, אם כי לעתים זקוקים לעתים לנקודת מבט של מישהו שעדיין לא התרגל לרעות החולות - ויכול להצביע עליהן, ועל האפשרות לעשות את הדברים טוב יותר.
בחובות הטכניים הגדולים לא קשה כ"כ לשכנע את ההנהלה - כי אפשר להסביר להם מה עובד לא בסדר, ויש לכך לרוב כמה עדויות.
הרבה פעמים קשה לשכנע בקיום חוב טכני משמעותי לפני שהוא מתחיל לתת את אותותיו, והרבה יותר קל לשכנע אחרי שנזק הולך ונגרם. יש הוכחות.
בתפיסת ה Lean Architecture, חשוב מאוד להבין את הדינמיקה הזו.
כאשר אנו מזהים חוב טכני שהולך להיות מיושם, שווה לעשות מאמץ ולנסות למנוע אותו מבעוד-מועד.
לא תמיד נצליח לשכנע שזה אכן מדובר בחוב טכני משמעותי - לפעמים פשוט לא תהיה הסכמה על קיומו של החוב או משמעותו. בפעמים אחרות, תהיה הסכמה - אך עדיין החלטה לקחת אותו ולהתקדם הלאה.
גם במקרים כאלו, לא כדאי להתייאש או לריב עם כל הארגון, על מה שהארגון כרגע לא מסוגל לראות.
עומדים לרשותנו עדיין שני כלים:
- לנסות להשפיע על סדר הפעולות, כך שחוב הטכני ייחשף ויוכח מוקדם יותר (ובשאיפה: עם נזק מינימלי).
- להשתיל "מנופים" לתיקון החוב: עדיף לתקן בדיעבד בקלות רבה יותר - מאשר ל"הילחם בטחנות רוח" ללא הצלחה.
להזכיר: גם אנו לעתים לא מבינים נכון את הדברים. ומה אם אנחנו טועים?
לפעמים, ניסיונות חוזרים ונשנים להתמודד עם חוב טכני מהותי - שהארגון מסביב לא מסכים להכיר בו הוא סימן שכדאי להחליף ארגון. זה עשוי להיות טוב לשני הצדדים - ובלי לקבוע מי באמת צודק. בסיבוב הבא (ב-2 הצדדים), כנראה שתהיה הפקת לקחים.
סיווג אחד (מני רבים) של סוגים שונים של חובות טכניים ומקורותיהם. מקור: Martin Fowler כדאי מאוד להימנע ככל האפשר מחובות טכניים משמעותיים ומיותרים. סיווג המקור - פחות חשוב. |
איך (כן) מחזירים חוב טכני?
- זיהוי החוב הטכני, וסיווגו ע"פ השפעה על המערכת / הארגון.
- שיקוף ושיתוף החוב הטכני, לחלקים שונים בארגון.
- מציאת המנגנון הארגוני לצמצום חוב טכני.
חוב טכני תמיד יגדל (עוד קוד נוסף, הביזנס משתנה, המערכת גדלה ונעשית מורכבת, הקוד מתיישן ו"נרקב") - וחשוב להוריד אותו בקצב שקול לגדילה - על מנת, לפחות, להישאר במקום.
הציד הוא דליל רוב ימות השנה, וחשוב להתמודד עם המחסור.
אבל מידי פעם, יעבור באזור עדר גדול של בפאלו נודד. שבט שמתחיל לפעול רק כאשר העדר כבר הגיע - לא ישרוד לאורך זמן. עליו להיות מוכן ליום הזה, ולנצל את ההזדמנות ברגע שהגיעה - עד תום.
באופן דומה, הזדמנויות לצמצום החוב הטכני, לא נופלות מהשמיים, ולא כל ימות השנה. עליכם להיות מוכנים עם תוכנית אופרטיבית - שכאשר יש הזדמנות ("אוי - יש לנו מפתח פנוי בחודש הקרוב"), אנחנו יודעים בדיוק מה לעשות, יש לנו מגוון אפשרויות - ואנו יכולים להפיק מההזדמנות את המירב.
ניהול "רשימת בעיות":
- כל פעם שאני מבין שיש פה חוב טכני בעייתי שארגון סובל בגללו (או שעומד להיות) - אני מוסיף אותו לרשימה.
- מדי פעם בצורה פרואקטיבית - אני יושב עם המפתחים הוותיקים, מעדכן ומתקנן את הרשימה.
- את הרשימה חשוב לתעדף. אם יש לרשות הארגון מפתח זמין לחודש, עדיף מאוד שיפתור בעיה חמורה שהנזק ממנה ברור - מאשר "לסדר קצת את הקוד". יצירת Impact חיובי הוא גם מפתח על מנת שהארגון ימשיך וירצה להשקיע בצמצום חובות טכניים בעתיד.
- אם יש בעיה ללא פתרון - זה לא עוזר. לפחות למספיק מהבעיות - חשוב שיהיה פתרון ידוע. אם צריך להשקיע ב Design - השקיעו מדגמית בכמה עניינים חשובים באזורים שונים. אי אפשר לדעת באיזה אזור של המערכת "יעבור עדר הבאפלו".
השיקוף של הבעיות - הוא חשוב מאוד גם כן. גם לצד ההנהלה, וגם לצד המפתחים:
- אם ההנהלה לא יודעת שיש בעיות חמורות, זה לא הוגן ולא אחראי. היא לא תדע להקצות את המשאבים (שתמיד נמצאים במחסור) בכדי להתמודד עם הבעיה.
- אם המפתחים לא מבינים שדברים מסוימים מהווים בעיה חמורה - הם לא ידעו לצמצם ולהגביל את הבעיה. מכירים את ה Anti-Pattern של "שכפול Anti-Patterns במערכת"?
- אם אתם לא מבינים את הבעיה, איך המפתחים לא יתקנו אתכם ויסבירו לכם - אם לא תדברו איתם על זה. תנו להם הזדמנות לתקן אתכם, ולחסוך לכם חוסר-נעימות.
מציאת המנגנון הארגוני לטיפול בבעיה:
זה לפעמים החלק הכי קשה, ואני מקווה עבורכם שזו לא "הבעיה שעל כתפכם בלבד".
בחלק הבא (והאחרון) נעסוק בה קצת יותר בהרחבה.
תפיסה נפוצה (נתקלתי בה כבר מספר פעמים) היא שיש להקצות זמן נתון (הכלל המקובל: כ 20% בזמן העבודה) לצמצום חובות טכניים.
גישת הצוות:
ברוח ה empowerment (עניין מבורך) מורים לכל צוות להקצות את הזמן שלו - מבלי שישתף את שאר הארגון כיצד הוא מנצל אותו.
זה לפעמים החלק הכי קשה, ואני מקווה עבורכם שזו לא "הבעיה שעל כתפכם בלבד".
בחלק הבא (והאחרון) נעסוק בה קצת יותר בהרחבה.
רשימה לדוגמה של חובות טכניים שיש לפתור במערכת. הרשימה רק תלך ותתארך, אז חשוב כל הזמן לפתור בעיות, לבדוק אלו עדיין רלוונטיות, ולתעדף. |
מציאת המנגנון הארגוני לצמצום חובות טכניים
תפיסה נפוצה (נתקלתי בה כבר מספר פעמים) היא שיש להקצות זמן נתון (הכלל המקובל: כ 20% בזמן העבודה) לצמצום חובות טכניים.
גישת הצוות:
ברוח ה empowerment (עניין מבורך) מורים לכל צוות להקצות את הזמן שלו - מבלי שישתף את שאר הארגון כיצד הוא מנצל אותו.
- כאשר המשאבים הם מקומיים (ברמת הצוות) - קשה עד בלתי אפשרי לפתור את הבעיות הגדולות.
- כבר נתקלתי לא-פעם בצוותים שניצלו את רוב הזמן שניתן להם בכדי לנסות טכנולוגיות "חדשות ומגניבות" שלא עשו שום השפעה חיובית משמעותית על המערכת או הארגון. זה בטח טוב לריצוי עובדים - ברמה כלשהי.
הגישה הגלובאלית:
לא פעם ראיתי שהוא תוקשר בצורה כזו שאנשי המוצר הרגישו ש"גוזלים מהם מזמן הפיתוח, בלי הצדקה" (מילים שלי).
למשל: בכל תוכניות העבודה מציגים 20% זמן טכני - ואנשי המוצר מתחלקים הזמן הנותר. זה נשמע כמו רעיון טוב על מנת להסביר מדוע לא כל המפתחים עובדים כל הזמן על משימות מוצר, אבל עלול בקלות לגרום לתחושה של אובדן משאבים מצד אנשי המוצר.
תגובה טיפוסית לתחושה כזו, היא לנסות ולהעמיס על "זמן החזרת החוב הטכני" כל מאמץ אפשרי: תיקוני באגים, כתיבת בדיקות-יחידה, או קבלת חובות טכניים במופגן - בידיעה שהם יכוסו מתקציב אחר. זה אף פעם לא מתחיל כך, אך זה בקלות עלול להתדרדר לשם לאורך הזמן. משאבי-פיתוח הם משאב יקר ערך בארגונים, ורק טבעי שברגע שיש "תקציב חדש" - רבים ינסו לנגוס בנתח ממנו להשגת היעדים הארגוניים שהם אמונים עליהם.
יתירות בפיתוח:
רעיון אחד שנתקלתי בו הוא הרעיון שיתירות בפיתוח (כלומר: יש יותר מפתחים ממה שצריך) - יאפשר לטפל בחוב טכני בצורה טבעית. זה רעיון הגיוני לוגית - אך לא ראיתי אותו אף פעם קורה בפועל:
- כל עוד איש מוצר יכול, בעזרת מצגת שהכין בשעתיים, ליצר עבודה לצוות פיתוח לחודשיים - לא יהיה לעולם זמן פיתוח "יתיר".
- עוד נקודת מפתח והיא יוקרה של צמצום חובות טכניים בארגון: כל עוד מירב מקבלי-ההחלטות בארגון מעריכים יותר פיצ'ר חדש מתיקון של חובות טכניים - הזמן שהוקצה להתמודדות עם חובות טכניים "יזלוג" לכיוון פיתוח פיצ'רים. כאן הפתרון הוא שיקוף יעיל של הבעיות הטכניות (עניין שהזכרנו קודם):
- חשוב שלמקבלי ההחלטות יהיה מושג על בעיות קיימות - ומה ההשפעה השלילית שלהן. הם לא יוכלו להבין את רוב הבעיות הטכניות - אבל כמה דוגמאות משמעותיות עשויות לעשות את ההבדל בתפיסה.
- חשוב שמקבלי ההחלטות יראו גם שבעיות נפתרות, או לפחות יחושו בצורה כלשהי שיש תרומה לחברה מתוך עיסוק בצמצום חובות טכניים (למשל: לשתף מכתב תודה של יחידה אחרת בארגון שסבלה מבעיה כלשהי).
- שיקוף אפשרי בעיקר לבעיות שנוגעות גם לביזנס בצורה ישירה (downtime, אטיות, פגעי-אבטחה), וחשוב לנצל תיקון של בעיות על מנת להדגים את החשיבות במערכת שלא רק כתובה - אלא גם כתובה נכון.
הבחנה חשובה היא בין חוב טכני "טוב" ו"רע": חוב טכני קצר טווח - הוא פעמים רבות שימושי ומועיל. למשל: מיקוד בשחרור מוקדם ולמידה. חוב טכני משמעותי ושנמשך לאורך זמן - הוא לרוב "רע" |
לפעול במהירות ובנחישות:
גישה שעשויה לעבוד עבור מגוון מקרים היא ניהול פנימי של החוב הטכני בתוך הפיתוח: מיד בסוף הפיצ'ר מקדישים כמה ימים על מנת "לנקות חובות" ולשפר את הקוד היכן שצריך.
- לפעמים זה חצי יום - ולפעמים שבועיים.
- לא מדווחים על סיום המשימה עד שלא מסיימים את החובות הטכניים המידיים. מסבירים שיש עוד כמה צעדים טכניים נדרשים לסיום המשימה.
- נקודת מפתח להצלחה היא מחויבות עמוקה של מנהלי הפיתוח, והיכולת שלהם לעמוד בלחצים מצד אנשי המוצר. אף אחד לא שמח לשמוח על פיצ'ר שמתעכב בשבועיים (גם אם שוחרר כרגע, ויש רק עוד סדרת תיקונים נדרשת).
- בארגונים מסוימים - עדיף לא לשקף לאנשי המוצר לאן הזמן בדיוק הולך. אולי רק בצורה ראקטיבית לשאלות.
- בארגונים שבהם יש יותר אמון הדדי - שווה לשקף, אבל להיזהר ולהסביר את ההשקעה בצורה שתבנה אמון עם היחידות העסקיות.
צוות לצמצום חובות טכניים:
בגלל שהבעיות לעתים דורשות השקעה ארוכה, ומומחיות - אחד המודלים הוא לייצר "צוות תשתיות" או צוות שיתקן בעיות במערכת.
למי שיש לו ניסיון בתוכנה, הרעיון הזה עשוי להישמע מופרך כמו הרעיון שעובדים outsource יבואו וינקו את הקוד (יבצעו refactoring) עבור המתכנתים של הארגון. אבל היי - גם דבר כזה קיים.
- בעיה עיקרית במודל הזה היא שחיקה של האנשים שבצוות.
- בעיה שניה היא שחובות טכניים רבים הם בליבת המודל הלוגי של המערכת. בלי היכרות אינטימית - לנסות לכתוב קוד טוב יותר זו משימה כמעט בלתי-אפשרית.
- יתרה מכך, גם מי שמכיר את המערכת מצוין ועסוק במשימות טכניות לאורך זמן ארוך - יאבד את הקשר עם פרטי המערכת, שמשתנה כל הזמן.
- אחת הווריאציות היותר הגיוניות לטעמי, היא שצוותים "משאילים" אנשים לצוות לצורך משימות של צמצום חוב טכני - ובסיום המשימה האדם חוזר לצוות.
- דרך ההתנהלות של הצוות שלא כפופים למחזור מוצרי (אם עובדים ב SCRUM) ותמיכה של אנשים טכניים חזקים - יכולה דווקא לעזור, ולייצר גיוון למי שמצטרף זמנית לכזה צוות.
- גם הקצאת המשאבים - היא קלה יותר לניהול, כאשר מדובר בצוות.
צמצום חוב טכני - כאירוע:
מודל אחר שיכול לעבוד הוא לרכז מאמץ של יחידה גדולה, או כל הפיתוח - על מנת לצמצם במרוכז חובות טכניים.
- וריאציה אחת ששמעתי עליה, היא חברה שמקדישה 3 ימים כל תקופה מסוימת - על מנת לשפר ולהעשיר את המערכת בבדיקות אוטומטיות (בדיקות יחידה, בדיקות אינטגרציה, וכו' - בדיקות שמפתחים כותבים). ע"פ הסיפור - זה עבד דיי טוב.
- וריאציה שניסינו לאחרונה בחברה הנוכחית שאני עובד בה (Next-Insurance) היא להפעיל את כל הפיתוח למשך שבועיים - על מנת להתמודד עם רשימת בעיות שהוכנה ותועדפה מראש.
- הזמן הארוך יחסית - מאפשר לפתור בעיות שהן לא רק פצפונות / נקודתיות.
- האמירה שיש השקעה משמעותית באיכות הטכנית של המערכת - משדרת מסר חשוב גם למתכנתים, וגם לשאר הארגון
- אני אישית, מאוד נהנה מתקופות כאלו.
בכל מקרה, חשוב לתת את הבמה הראויה לתיקון של חובות טכניים משמעותיים - להלל ולהעריך בפומבי את מי שפתר בעיה מהותית. ההוקרה גם מצדיקה עבודה שהיא פעמים רבות קשה ומתישה, וגם משדרת בארגון שאנו מעריכים הנדסה טובה - ולא רק עמידה ביעדים ("בכל מחיר").
סיכום
שוב אמרתי לעצמי, שאבחר נושא קצרצר לפוסט, ואכתוב משהו באורך 4 tweets לכל היותר. לא הצלחתי - היה לי יותר מה לומר משחשבתי.
כמה דגשים שחשוב לי שלא תצאו מקריאת הפוסט בלעדיהם:
- נקודת האופטימום הארגונית היא בהחלט לא "אפס חוב טכני", או לפחות לא בתפיסה המקובלת. "מקסימום הנדסה" - היא לא מקום טוב לביזנס או למערכת חיה להיות בו. חשוב לקחת כמה סיכונים, ולהתקדם בקצב טוב.
- "חוב טכני" הוא מושג מאוד סובייקטיבי. בהגדרה מסוימת - רעיון החוב הטכני עשוי להתרגם לאיסוף עבודה חסרת חשיבות.
- חשוב חשוב חשוב להתמקד בטיפול בחוב טכני שיש לו השפעה חיובית מורגשת (Impact).
- לעתים יש חוב טכני (Design, שמות של משתנים) שעצם קיומו מציק לנו כמהנדסים, אבל אין לו חשיבות לפעילות המערכת.
- הייתי משקיע מעט עבודה (low hanging fruits) עבור ההרגשה הטובה, בנוסח "החלונות השבורים" (לשמר אווירה של אכפתיות במערכת)
- הייתי מתאמץ לקבל גם אלמנטים לא-אלגנטיים במערכת, ואפילו צורמים - כל עוד העלות / תועלת לפתור אותם היא לא סבירה. למשל: עניין ה referer ב HTTP.
- מערכות מתחדשות מטבען. אם תתעדו ("רשימה") ותשתפו ("שיקוף") בבעיה - יש סיכוי טוב שבשכתוב הבא המצב יהיה טוב יותר.
- הכי מעצבן זה לראות קוד ששוכתב ושימר חובות טכניים מהותיים - מחוסר הבנה.
- חוב טכני לא צריך להיפתר לחלוטין. הורדה של בעיה מרמת Critical לרמת Medium - עשויה להיות התקדמות חשובה ומספיקה.
- בפעם הבאה שנרצה לשפר משהו, כנראה שנבחר בעיה קריטית אחרת - על פני העלמה של בעיה בעלת חומרה בינונית.
- למרות ש"חוב טכני" הוא עניין בד"כ עניין טכני וטכנולוגי - מציאת המנגנון לצמצום חובות טכניים הוא בעיקר ארגוני. עבדו עם ההנהלה ומי שיכול לקדם דברים בארגון - לא רק עם מקצועני התוכנה.
שיהיה בהצלחה!
פוסט מצוין
השבמחקמעולה כרגיל.
השבמחקהבעייתיות הכי גדולה שהייתי מונה בתצורה בה יש צוות תשתיות לטיפול בחובות טכניים: זה מסית את האחריות מהמהנדסים הראשונים לייצר תוכנה טובה. וברגע שהאחריות על האיכות היא לא על המבצע הראשי, הו שם ההפרשות פוגעות במתקן הקירור :)
אגב באג Y2K
השבמחקבאג Y2038 בדרך...
- משה
מאמר מצויין אפילו יותר מבדרך כלל!
השבמחקאכן, רוח דומה של דברים.
השבמחקתודה רבה על השיתוף!
וחבל שהפסקת לכתוב...
היי ליאור, מאמר נהדר תודה על השיתוף! אשמח להבין את החלוקה לקטגוריות איך הגעתם לקטגוריות הספציפיות האלו? והאם יש מצבים שתבחר מספר קטגוריות למשימה מסוימת בהנחה שהיא נוגעת ב2 קטגוריות או יותר?
השבמחק(אני עוסק בארכיטקטורת קליינט)
הטקגוריות הן סתם כלי ארגון בסיסי. לעשות קצת סדר במשימות, ולנסות להבין כמה מסוג א׳ וכמה מסוג ב׳. החשיבות שלהן משנית.
מחקמשימה יכולה להיות ב -2 קטגוריות, ואנחנו בוחרים מה לבצע ע״פ רמת חומרה וע״פ הזדמנויות (נניח: עושים שינוי באזור הזה בקוד בכל מקרה) - ולא פי קטגוריות.
תודה על התגובה, איך אתה מעריך רמת חומרה של חוב טכני? אשמח לפירוט
השבמחקבמתינות.
מחקתמיד אפשר לגלוש להיסטריה ("אם לא נעשה את זה - המערכת תהיה אטית / מפתחים לא יתקדמו לעולם / נצטרך לכתוב הכל מחדש / המערכת תקרוס כל לילה / ילדים יפרצו למערכת ויאספו מידע פרטי").
אם אם נותנים לכם את המנדט (לשם אתם צריכים לחתור) - להשקיע זמן משמעותי של מפתחים להחזיר חוב טכני - כמה ערך ממשי אתם הולכים ליצר לחברה? כמה אתם בטוחים לגבי זה - וכמה זה יהיה ניכר?
זה השלב שבו דברים נהיים יותר מורכבים: מאוד מרגיז ומפריע שבקוד משתמשים באבסטרקציה ZX מאוד לא נכונה ומבלבלת, אבל החלפה גורפת שלה תהיה כ"כ יקרה וקשה - וייתכן שלא תשרת את צורך הארגון. מקסימום היא תנקה היסטוריה לא יפה שלא נעים להביט בה (ואתם, אם אתם בפרטים, הרי מביטים בה כמעט כל יום).
חשוב שהמשחק יהיה מסביב לעלות - תועלת. אם נשקיע ככה עבודה - כמה תמורה נשיג. כמה התמורה הזו משמעותית באמת? מה היה קורה לו לעולם לא היינו מסדרים את הדבר הזה.
מערכת מושלמת היא כשלון הנדסי.
למה? כי קרוב לודאי שהשקענו הרבה מיד זמן - בדברים לא חשובים.
חשוב למצוא כיצד החזרה של חוב טכני היא ROI Positive (כלומר: התמורה גדולה מההשקעה, בצורה ברורה) - וזה הבסיס העיקרי להשקעה. מאוד קשה לכמת את הערך של "סדר במערכת" או "הסרה של פרקטיקות רעות בקוד - כדי שאנשים יפסיקו לשכפל אותן", ולכן יש פה הרבה עניין של ניחוש והערכות גסות.
אני חושב שמה שעוזר לקבוע במה להשקיע הוא להשוות אייטם אחד לשני: מה יותר חשוב? שנסדר את X או את Y?
אם התחלנו באייטמים החשובים ביותר (עפ תעדוף), ובשלב מסוים יש לנו ספק לגבי ה ROI של מה שאנחנו עושים - זו הנקודה לעצור. סיכוי טוב שעשינו מספיק לבינתיים.
מקווה שהצלחתי להעביר את הרעיון.