יום שבת, 20 בפברואר 2016

ארכיטקטורה: האם לנסות שוב?!

לעתים אנו נתקלים בעת בניית המערכת בבעיות שקשה לפתור.

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

מה עושים ב 0.1% (עשירית אחוז) מהמקרים האחרים, כאשר דווקא מודול B מסיים ראשון?

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

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

סוג אחר של מתכנתים, יחפש פתרונות אג׳יליים ופשוטים למימוש. ״בוא נוסיף sleep של 500ms למודול ב׳ - וכך הוא תמיד יסיים אחרי״. הפתרון אמנם פשוט מאוד למימוש אך הוא נדחה על הסף על ידי הצוות: להאריך את התהליך כולו סתם בחצי שניה, עבור 99.9% מהמקרים  - זה לא נשמע סביר...
ננסה שוב: ״בואו נזהה מצב שמודול ב׳ מסיים ראשון, ואם זה קרה - נפעיל את כל התהליך בשנית״.

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

מה אתם אומרים?





אני באופן אישי מעדיף כמעט אוטומטית את הפתרון הראשון. נשקיע יותר - ונדע ״שהכל סגור״. לפתור את הבעיה ״אחת ולתמיד״. "שונא סיכון" - קוראים לזה.

כשאני מנסה לעשות realization לרצון הטבעי שלי אני מעלה גם ש:
  • תקלה של אחד למיליון היא עדיין תקלה. למה לתכנן משהו כך שיישבר (אפילו שהמקריות היא אחת-למיליון)??
  • הפעלת אותו התהליך פעם שנייה אינו דבר צפוי. אדם נוסף שייכנס לקוד עשוי לפספס / לא להבין זאת. 
    • עובדה שאין בעיה להפעיל את התהליך פעמיים כיום. מי מבטיח שתנאי זה לא ישתנה בעתיד? וכאשר הוא ישתנה - מישהו יזכור שיש לנו טריגר שמפעיל את התהליך פעם נוספת ויידע / יזכור לתקן את המנגנון?
  • אמנם תקלה למיליון לא נשמעת חמורה, אבל מי מבטיח לנו שתחת עומס / לחץ, המערכת שלנו לא מתנהגת אחרת? אולי תחת עומס מסוים - התופעה תתרחש אחת למאה פעמים?!

מצד שני יש כמה טיעוני-נגד:
  • המערכת שלנו עוד טרייה ותעבור שינויים רבים. להשקיע עכשיו יומיים בפתרון מקרה קצה - זו השקעה לא מידתית.
  • תקלה של אחד למיליון זה סיכון שניתן לקחת. בואו נהיה דוגריים: במערכת כנראה קיימים (ובעתיד יווצרו וייפתרו עוד ועוד) באגים אחרים שיגרמו להרבה יותר מ"תהליך אחד למיליון" להיכשל. עשינו Framing לדיון כאילו כל המערכת מושלמת - וזו הבעיה האחרונה שנותרה בה. זה לא המצב.
  • אחד למיליון נראה בעייתי? בואו נעשה ניסיון שלישי - אם צריך. בואו נזרוק Alerts למוניטורינג כאשר זה קורה - ונלמד אם באמת יש בעיה.

באיזה גישה אתה הייתם בוחרים?



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

התבונה המקובלת היא: "בואו נעשה את זה פעם אחת ולתמיד".


באופן טבעי בארגונים קטנים וצעירים (אימפרבה, Gett - לא מאוד קטנים / צעירים) הנטייה המקובלת היא לגישה השנייה.
בהקצנה: ראיתי פעם ניסיון להוסיף שימוש חדש לטבלה קיימת (עם משפטי if שונים בקוד) - בכדי להימנע מיצירת טבלה חדשה.

התבונה המקובלת היא: "בואו לא נסבך את זה".


אלתור. יעיל, או חפלפ?  מקור: redstateeclectic

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

במשך שנים בקריירה, הצעות מסוג זה נתפסו על ידי כחוסר מקצועיות, הבנה, או סבלנות נדרשת. כסמל של התנהגות שיש להוקיע. עבדתי אז ב SAP וקיבלתי גיבוי מלא לגישה הזו מעמיתי והמנהלים. פעמים רבות עבדנו עוד שבוע או שבועיים - בכדי לא להגיע לפתרונות של "ניסוי שני". לעתים, כאשר היה מדובר בשבועות רבים - היינו "מתגמשים" (ורושמים עוד שורה באקסל ה Technical Debt [א] שאז ניהלתי).

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


הבהרה: לא כל פתרון שיש בו אלמנט של "Retry" הוא בהכרח סוג הפתרונות שאני מדבר עליהם בפוסט. יהיה אולי נכון יותר לסווג את סוג הפתרונות בהם עוסק הפוסט כפתרונות "מהירים ואופטימיים" (למשל: כמו הוספת ה sleep, קביעת ערכי ברירת-מחדל שיגרמו ל flow להמשיך ולעבוד, וכו'). אפשר לקרוא את הסיפור כיצד ייצבנו את המערכת שלנו בעזרת הכנסת retries לקריאות בין מיקרו-שירותים בפוסט הזה. זה לא היה בדיוק סוג ה Retry שאני מדבר עליו, כי זה לא "ניסיון מהיר ואופטימי". זה היה ניסיון "יסודי, מבוסס ומנומק - אך אופטימי" - משהו באמצע. הוא היה מגובה בנתונים ובחשיבה יסודית, אך אכן לא היה לנו שום בטחון שנשיג תוצאות בעקבות השינוי.

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


לא ספר אמיתי :-)



אז מה אני חושב על פתרונות "מהירים ואופטימיים"?

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

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

"לפתור את הבעיה אחת ולתמיד" זו בעצם הגישה שאומרת להשקיע יותר בפתרון, ו"בוא לא נתעכב" זו בעצם הגישה שאומרת (you ain't gonna need it (YAGNI - להשקיע פחות.

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

צעד שני הוא לשאול את השאלות הבאות:
  • עד כמה חלק הקוד המדובר הוא קריטי להצלחת הביזנס? עד כמה הוא מורכב ואנו סובלים מתחזוקתו? - ככל שהוא יותר מורכב ורגיש, נכון להשקיע יותר משאבים ולצמצם סיכונים.
    • מצד שני: ככל שמדובר באיזור קריטי למערכת - סביר יותר להניח שנחזור ונתקן / נשפר את ה "Retry" אם הוא לא מספיק טוב.
  • עד כמה המערכת צעירה / בוגרת? ככל שהמערכת בוגרת - יש טעם להשקיע יותר בכדי לשמר את האיכות והיציבות שהיא כבר השיגה. במערכת ממש חדשה - תקלה אקראית עשויה להיבלע בזרם בעיות גדולות וחמורות יותר. בעיות גדולות יותר יכולות להיות באגים, אך לא פחות מכך הן יכולות להיות פיצ'רים חשובים שחסרים ללקוחות, או אי-התאמה בסיסית לצרכים העסקיים.
  • עד כמה ההתנהגות שאנו יוצרים היא צפויה? (Principle of least astonishment) - ככל שהפתרון ה"אופטימי" שלנו הוא מפתיע ולא-צפוי (יחסית להתנהגות הסדירה והמקובלת של המערכת) - כך גדלה הסבירות שהוא יישבר עם הזמן, או יגרום לבעיות שיהיה קשה לצפות. 
  • עד כמה קל לדעת אם ה Retry עובד? אם יש לנו שטף של אירועים מבוקרים ומנוטרים - קל יותר להצדיק התנסות ב"פתרון מהיר ואופטימי". סיכוני אבטחה (אירועים נדירים יחסית, אך אולי עם השפעה חמורה), למשל - הם מקום פחות מומלץ לעשות בו ניסויים.
    • הוספת Alerts למצבים בלתי צפויים סביב הפתרון - עשוי להיות מעשה נבון.
  • אל תנהגו בטיפשות. אל תעשו Retry על פעולות שאינן idempotent - כלומר פעולות שהפעלה שלהן מספר פעמים תסתיים בתוצאה שונה מהפעלה בודדת (למשל: חיוב של כרטיס אשראי).

בקיצור: It depends.


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




---

[א] מונח המתאר את ה"חובות הטכנולוגיים במוצר". כמו חובות פיננסיים, נבון לעתים לקחת אותם - אבל אם הם תופחים הריבית היא בלתי-נשלטת ועלולה להוביל לאסון.
במילה Debt, אגב, לא מבטאים את ה b. זה נשמע כמו "Technical Det".




יום שישי, 5 בפברואר 2016

איך (לא) לבצע בחירות טכנולוגיות עבור המערכת שלכם?

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

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

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


ישנו ניסוי מוכר בו מציבים דוכנים עם פריטים למכירה (בווריאציה שאני מכיר: תכשיטים):
  • דוכן ראשון - עם 6 פריטים בלבד.
  • דוכן שני - עם מבחר של כ-30 פריטים.

כיצד יהיה שונה דפוס הקנייה בשני הדוכנים?

על פניו: אנשים אוהבים זכות בחירה. כשיש יותר פריטים - יש יותר סבירות שאמצא משהו שתואם לטעמי (הגיוני).

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

כי אנשים מתקשים לבחור. בחירה בין 30 פריטים היא קשה יותר מבחירה בין 6 פריטים - כך שהדוכן בן ששת הפריטים מצליח למכור יותר (חיזוק חיובי לחנויות מעצבים / high-end).



באופן דומה, קרה בעשור האחרון תהליך דומה בעולם התוכנה:
  • אם פעם היה Framework דומיננטי לכל שפת תכנות (STL ל++C, בג׳אווה JEE, ובדוטנט - מה שמייקרוסופט סיפקה) - עם הזמן מבחר ה frameworks הלך וגדל.
    ג׳אווהסקריפט היא הדוגמה הקיצונית לשימוש ב micro-frameworks. הבדיחה הנפוצה היא על מפגש מתכנתים שמתנהל כך: ״שלום, אני ליאור - וגם אני כתבתי Framework לג׳אווהסקריפט...״.
  • כיום, ה Technology Stack - "מתפוצץ מאפשרויות": יש לנו את Nano Server, Deis, Fastly, את Spark (על כל חלקיו) ואת Kubernetis. כל שבוע יוצאת טכנולוגיה / ספריה חדשה ומדליקה!
    האם אתם כבר מכירים את Axton, Sleepy Puppy, שפת Nim ושפת Julia? אל תחשבו אפילו לומר שלא בדקתם את OneOps של וולמארט...
  • בסיסי נתונים: אם פעם הבחירה הייתה ברורה (אורקל - באנטרפרייז, SQL-Server - ל Microsoft-shop, ו MySQL לסאראט-אפים) היום יש יותר מכמה בסיסי נתונים רלוונטיים לכל סביבת עבודה. למשל: MongoDB, Redis, ו Cassandra יכולים לשמש את כולם - בנוסף לבחירות המקוריות. בעולם ה open source כבר אין בסיס נתונים דומיננטי אחד: MySQL, אולי PostgreSQL ואולי MariaDB? מה עם Aurora?
  • המושג ״Polyglot Persistence״ או ״Polyglot Programming״ (המתאר סביבה רבת-טכנולוגיות) עלול לעזור ולהצדיק מצב של שימוש בריבוי טכנולוגיות במקביל [ד] - אבל הוא לא מפשט את הבחירה.
    Stack טכנולוגי רחב מידי - הוא עדיין בעיה תפעולית ממעלה ראשונה. איזו רמת עומק ממוצעת אתם רוצים בטכנולוגיות שאתם עובדים עימן? ככל שיהיו לכם יותר טכנולוגיות - רמת העומק הממוצעת תפחת.



מקור: modulecounts.com

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



כיצד אנו מתמודדים עם הקושי לבחור - כאשר המבחר גדול?


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

בעולם הצרכנות יש לנו יוריסטיקות לקנייה:
  • המלצה של מגזין / מקור ״בעל סמכות״ (לכאורה!) - תשפיע עלינו לטובה.
  • המלצה של אדם ממשי אחד שאנו מרגישים שהוא דומה לנו - לרוב תהיה חזקה יותר מהמלצה של "מקור סמכותי".
  • מה שיקר יותר - בטח טוב יותר [א].
    • טרנד של הדורות האחרונים: מה שחדש יותר - בטח טוב יותר [ב].
  • הצמדות למותגים ידועים.
    • למרות שמי שבחן פעם מוצרים לעומק - יודע שזו יוריסטיקה חלשה: מותגים ״חזקים״ לעתים קרובות מייצרים גם מוצרים חלשים / לא-תחרותיים / יקרים ללא הצדקה.

מה אנו עושים כ״מקצועני-תוכנה״? - בערך את אותו הדבר!

אנו נצמדים לשמות גדולים, למותגים, להמלצות של אתר / בלוג , והמלצות של חבר, לדברים חדשים ויקרים (במידת האפשר). הבחירות שלנו הופכות יותר "אופנתיות", ופחות "לוגיות".

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


אז זו לא בחירה "מקצועית נטו"?

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

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

הנה כמה קריטריונים שעוזרים להבין אם מדובר בתהליך בחירה או תהליך הצדקה:
  • אם הדיון הוא קיצוני, והאלטרנטיבות מתוארות לחלופין כנפלאות ("Rocks") או איומות ("Sucks") - זהו כנראה דיון רגשי.
  • אם יש אלנטרטיבה יחידה: "Angular.js זו הבחירה הנכונה", אבל לא מוכנים לדון ברצינות ב Ember.js או React+Flux (שהן דיי מקבילות) - כנראה מדובר בדיון רגשי.
  • אם מוכרים לנו את הטכנולוגיה כמו שמוכרים ביטוח - אז זה כנראה תהליך הצדקה.
    • איך מוכרים ביטוח? מתמקדים בתסריט קיצוני ומבהיל ("ואם הבית שלכם יהרס ברעידת אדמה...") בכדי להצדיק מחיר מסוים ("לא היה עדיף לשלם 3000 ש"ח בשנה?"). כאילו שאם הבית יהרס ברעידת אדמה חברת הביטוח לא תציב בפנינו כל קושי אפשרי בכדי שנקבל כמה שפחות כסף... תוך התעלמות מסבירות (מעולם לא קרה...) תוך התעלמות מנזקים אחרים (שחלילה - עלולים להיות קשים יותר)....
    • איך מוכרים טכנולוגיה כמו ביטוח?
      • "אבל בריילס יש הגנה בפני cross request forgery - וב Java האתר יהיה פרוץ להתקפות (!!)"
      • או: "אם אתה צריך לטעון סט של 5GB נתונים זה ייקח פי 10 זמן (!!)" (בעוד אנו לא חיים עם dataset בגודל דומה לזה בכלל). "חבל לאבד את כל הלקוחות שמייד יעזבו את החברה, וישמיצו אותה בפייסבוק ללא הפסקה, יום - ולילה!"

מק עם סטיקרים => הצהרה אופנתית!

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

ניתן "להעריץ" ספריות ומותגים ("גוגל", "HashiCorp"), גם מבלי להבין או להתנסות במוצר.
כיום אנו נוטים להעריץ חברות אינטרנט בעלות Scale גדול ושווי בורסאי גבוה ("חדי-קרן"). העתקת הארכיטקטורה של חברה שמטפלת בנתונים בנפח 20PB ביום - לא בהכרח ישרת את הצרכים העסקיים של החברה שלנו. הדרך להגיע ל Scale גבוה היא בפשרות כואבות. האם אנו מעתיקים פשרות שהארגון שלנו לא צריך לעשות?

פידבקים חיוביים מחברים / עמיתים ("וואו! אתם עובדים עם unikernel? דוקר זה באמת כ"כ 2015!!!!") - תבצר את עמדתנו. האם לא נרצה עוד מהתחושה הטובה הזו?!

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

שמירה על מוטיבציה גבוהה בקרב המפתחים הוא אתגר שמעסיק כמעט כל חברה. גישה ניהולית מסוימת היא "לתת למתכנתים את הטכנולוגיה שהם רוצים" - עבור המוטיבציה שתנבע מכך. מתכנתים רבים באמת מאמינים ששימוש בטכנולוגיה מגניבה הוא שיגרום להם לאושר.

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


ראיתי את הניסיון לתת למפתחים "חופש טכנולוגי כמעט-מלא" בפעולה, ואני חושב שזו גישה שכדאי לנקוט בה במשנה זהירות:
  • האמונה שטכנולוגיה מגניבה תגרום לאושר - לעתים מתבדה במהירות. בכל טכנולוגיה יש גם צדדים פחות נעימים ויפים. פעם ראיתי מתכנת שדחף לעבוד בטכנולוגיה x, אבל אחרי שבועיים בלבד של עבודה - כבר היה מבואס ממנה.
    אולי חוסר הסיפוק של המתכנת נובע ממשהו אחר? יכולת השפעה / הכרה בעבודה שלו / הרצון להתפתח - ויש דרכים טובות יותר להשיג זאת?
  • הסיפוק הרב של מפתחים מטכנולוגיה חדשה מתרחש הרבה פעמים מעצם כך שהם אלו שמובילים את ההכנסה של הטכנולוגיה (בייחוד אם אחרים גם ישתמשו בה). על כל מתכנת מוביל יש כמה מתכנתים מובלים, והם עשויים להינות פחות מהמצב שנוצר. כלומר: סיפקנו אדם או שניים, וביאסנו אחד או שניים אחרים (בעוד לעוד כמה זה לא ממש משנה...).
    זה מזכיר לי את הבן הקטן שלי, שמתעקש לבחור את הגופיה הלבנה בעצמו (כולן זהות) - וחס וחלילה לא ללבוש את זו שאני בחרתי עבורו. העניין הוא עצם ביצוע הבחירה - ולא הבחירה עצמה.
  • מה קורה, שכעבור שנתיים - הטכנולוגיה הזו כבר נחשבת "ישנה", ומתרבים המאמרים שמשמיצים אותה? מי יתחזק את הטכנולוגיה הזו, ואולי עוד טכנולוגיות רבות אחרות כשאנשים יתחלפו / יהיו עוד ועוד טכנולוגיות במערכת?
אני לא טוען שיש להתעלם מהצורך של מפתחים בטכנולוגיות חדשות. זה צורך שכנראה קיים, במיוחד אצל מפתחים שעדיין לא ניסו את החוויה. האם יש לכם חברה מלאה במפתחים צעירים, אולי?
חשוב לספק את הצורך הזה אצל המפתחים, אבל לנצל את ההזדמנויות בהן "הטכנולוגיה המגניבה" באמת מתאימה לצרכים - ולעתים יש לחכות להזדמנות הזו זמן-מה. הכנסה של טכנולוגיה מגניבה כאשר הצידוק היחידי הוא "מפתחים רוצים" (והם מוכנים גם להמציא עבורה צורך...) - היא גישה מאוד לא מומלצת.

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

פירמידת הצרכים של המתכנת?!



בענייני אופנה ניתן לזהות עוד 2 תופעות:

ישנן אופנות מתפרצות, שקצב האימוץ שלהן הוא לא-רגיל. פעם זה היה Rails, מאוחר יותר אולי MongoDB והיום זה Docker וגם Node.js ו Angular.js. הן לרוב פורצות בהובלת מובילים טכנולוגיים (שהם גם כריזמטיים), אבל לא דיי בזה להסביר את התרחבות התופעה - אולי ניתן להסביר אותה בעזרת שילוב של כמה מרכיבים [ה].
בקצב אימוץ של אופנה מתפרצת, סביר שרוב האנשים שהולכים לאחר האופנה לא ידעו להסביר מדוע באמת הכלי המדובר טוב יותר עבור המקרה שלהם. הם גם כנראה לא יהיו בעלי הבנה עמוקה בטכנולוגיה. בעיניים נוצצות הם יאמרו ("אני? אני עוד לא כזה מבין... יש לי עוד הרבה מה ללמוד"). הם יידעו בעיקר לדקלם כמה סיסמאות נפוצות "ב node.js אפשר לפתוח מיליון (!!) connections מלפטופ פשוט. אתה יכול לעשות את זה בג'אווה?!?".

כמו בכל אופנה יש אנטי-אופנה. שימוש ב Erlang או שימוש ב MySQL כפי שמתארים Wix או Uber כ"בסיס הנתונים ה NoSQL-י הטוב ביותר". אנטי-אופנה זה לבחור את הכלים הכי לא-נוצצים, ולהוכיח לכולם שבעזרת קצת כשרון - ניתן לעשות איתם הכל, ואפילו יותר מ buzz.js@node.

אני, דווקא מעריך יותר את האנטי-אופנה. אולי זה פשוט הסגנון האופנתי האישי שלי....



מי בוחר את הטכנולוגיה?


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

"חצץ"?!
פעם עבדתי עם צוות שנדרש לשכתב את כל קוד הג'אווה שלו ל Stored Procedures בתוך בסיס הנתונים. זו הייתה החלטה של ארכיטקט מאוד מאוד בכיר - ולמרות שהייתה התנגדות רבה, ההחלטה עמדה בעינה.
הצוות היה מאוד מתוסכל (ראיתם פעם אלפי שורות קוד של stored procedures?!) - ולאחר כמה חודשים של עבודה מייסרת, הארכיטקט המאוד מאוד בכיר נאלץ לוותר על ה"אוטופיה ארכיטקטונית" שלו (שלא היה בה שום דבר להתגאות ...).

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

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


מקור: Technology Radar של Thoughtworks




ומה אומרת הארכיטקטורה?


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

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

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

הטכנולוגיה? אולי אי-אפשר בלעדיה - אבל היא גם מפריעה!
  • למה אכפת לי איזה בסיס נתונים נשתמש? - עדיף להגדיר ארכיטקטורה שלא תלויה בכך. בפרויקט FitNesse המפתחים דחו את הבחירה בבסיס נתונים ועבדו עם מערכת קבצים "בינתיים". השנים עברו - ולא התגלה צורך מעשי בבסיס נתונים - וכך נותרה המערכת.
  • למה משנה שפת התכנות? כל בחירה תציב לנו מגבלות אחרות, ומי רוצה מגבלות?!

בסופו של דבר חשוב בצד הארכיטקטורה:
  • לצמצם את מספר הטכנולוגיות החופפות - כי ריבוי טכנולוגיות מקשה על תחזוקת המערכת, והארגון שלה.
  • למצוא טכנולוגיות "מספיק טובות" - שלא יגבילו אותנו יותר מדי.
    • ריילס - מציבה Overhead גדול של ביצועים. היא לא מספיק טובה למערכות עם High Throughput.
    • כתיבה ב C לא תציב מגבלות High Throughput אבל הקוד ייכתב באטיות ויהיה קשה לארגון ותחזוקה. היא לא מספיק טובה לצרכים עסקיים של מערכת שתפותח מהר.
אבל לבחור IDE? לבחור Application Server? ארכיטקטורה שכוללת או לא כוללת Docker? להתעקש רק על שפת תכנות ספציפית? - זו כנראה לא ממש "ארכיטקטורה", אלא ארכיטקט שמנצל את כוחו - כי גם הוא רוצה לבחור טכנולוגיות! מה לעשות - גם הוא בן-אדם שחובב טכנולוגיה.

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





זו איננה ארכיטקטורה!


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

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

אי אפשר כמובן לומר - כי לא מספרים לנו בתרשים על המערכת, אלא על סט הכלים שמרכיב אותה.
זה כמו לנסות ולהבין חפץ - ע"פ הכלים שבהם הוא נבנה: "משור, פטיש ומסמרים" - מה זה יכול להיות?! כסא, שולחן, אולי ספרייה או סוכה? האם כל מה שנכון וטוב לבניית כסא - נכון ומתאים גם לבניית סוכה?


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

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

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



סיכום


בחירה טכנולוגית היא לא מה שהייתה פעם (קרי: לפני עשור). פעם היו מעט טכנולוגיות, ותהליך בחירה שמפשפש בפרטים ועושה השוואות בין 2-3 אלטרנטיבות היה אפשרי. גם בחירה טכנולוגית הייתה נעשית פעם בשנה, ולא פעם בחודשיים.

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

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

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


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


----

לינקים רלוונטיים

על העוצמה הטמונה ב"טכנולוגיות משעממות" [דעה] (פוסט שלי)

Carburetor 21: Predictions for 2016 פרק (מוצלח!) של הפודקאסט "רברס עם פלטפורמה", שהחלק הראשון שלו עוסק בבחירת טכנולוגיות.

----

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

[ב] - בכנס GOTO; Berlin 2014 הייתי בהרצאה על big data של הוצאת ספרים גדולה. נתון מעניין שהם הביאו שספרי מחשבים נמכרים בעיקר בשנתיים-שלוש לאחר שיצאו. באופן דומה - גם ספרי ניהול אימצו דפוס דומה, אם כי שיטות הניהול לא משתנות משמעותית במחזורים הקצרים מ 10-15 שנים.

[ג] למשל: 2 פסיכולוגים קנדיים הראו את ההתנהגות הבאה: במירוצי הסוסים הם תשאלו מהמרים רגע לפני ההימור, וגם רגע לאחר ההימור (לאחר שהמהמרים כבר "שמו" את הכסף).
לפני ההימור היה להם בטחון נמוך יחסית לגבי איזה סוס ינצח.

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

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

עקרון זה נקרא בפסיכולוגיה עיקרון העקביות (The consistency principle). הצורך של אנשים בעקביות - וההתנהגות שלהם שנוטה באופן טבעי לחזק את העקביות בעולם האישי שלהם.

מקור: Influence של ציאדיני, פרק 3.


[ד] הבהרה: אנשים רציניים שידברו על Polyglot Programming יציגו גישה לפיה עובדים עם מספר כלים - השונים מהותית זה מזה.

"node.js ו Java" או "פייטון, רובי, ו PHP" - הן לא דוגמאות ל Polyglot Programming בריא - אלו שפות דומות מדי זו לזו, וריבוי שלהן בעיקר יציב בעיות תחזוקה. דווקא שילוב כמו "PHP וג'אווה" או "רובי ו ++C" - הם שילובים רלוונטיים.

[ה] הספר "The Tipping Point" (המעניין!) של מלקולם גלוודוול מנסה לנתח את הדינמיקה של תופעות שכאלו.