2014-05-24

צינורות ומסננים

בפוסט זה אני רוצה לדבר על Pipes And Filters (בעברית: "צינורות ומסננים", בקיצור: PAF).

אז מה זה PAF?
  1. האם זהו סגנון ארכיטקטוני?
  2. אולי Design Pattern?
  3. אולי סתם רעיון?
כל התשובות נכונות!
PAF יכול להיות סגנון ארכיטקטוני - במידה ויש מערכת שרובה בנויה בצורה זו. אם עוסקים במודול במערכת - אזי ניתן להתייחס ל PAF כ Design Pattern. באופן כללי - זהו רעיון.
אנו נתייחס אליו כרעיון, בכדי לא לתת לבאזז ("סגנון ארכיטקטוני") להסיט אותנו מהעיקר.

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


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



צינורות ומסננים - כמטאפורה


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

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

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



"צינורות ומסננים" כתהליך פיתוח תוכנה


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

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

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

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







"צינורות ומסננים" כארכיטקטורה / סגנון ארכיטקטוני


PAF הוא גם תיאור של מבנה של תוכנה. מבנה זה יתאים ל:
  • "מנוע חישובי" - בו יש הרבה פעולות לוגיות של חישוב ומעט / ללא אינטגרציה למערכות אחרות או I/O.
  • חישוב מסובך אותו נרצה "לפרק" ליחידות קטנות ("Divide and Conquer") בכדי לפשט.
  • חישוב נתונים ב stream - כאשר המידע מגיע בהדרגה או גדול מדי בכדי להכיל בזכרון.
  • מערכת בה נרצה לעשות שינויים בדרכי עיבוד הנתונים, על בסיס הפונקציות שכבר קיימות ("חיווט מחדש") או ע"י הוספת פונקציות.
אסביר את הנקודה האחרונה: בד"כ שמדברים על PAF בארכיטקטורה, מדברים על מצב בו ה interfaces של Pipe ו Filter הם אחידים במערכת, ומאפשרים מודולריות גבוהה. בהקבלה למטאפורה בתחילת הפוסט: קו ייצור כימי בו כל חיבורי הצינורות והמכלים הם סטנדרטיים / אחידים - כך שניתן כל יום לבצע שינוי בתהליך ע"י שינוי הסדר בין שלבי התהליך.
ארכיטקטורת PAF שכזו היא לא רק רשת של פונקציות חישוביות שמעבירות ביניהם נתונים - היא נבנתה בכדי לערוך / ליצור קשרים חדשים בין הפונקציות בקלות ובמהירות. היא עושה בעצם את ה tradeoff הבא:

גמישות לשינויים בצורת החישוב + עלות תחזוקה נמוכה (לשינויי "חיווט")  >  ביצועים 

ארכיטקטורת PAF היא בד"כ איננה הדרך היעילה ביותר (מבחינת ניצלות משאבים) לבצע את החישוב: יש העתקות רבות בזיכרון, cache trashing של זיכרונות המטמון במעבד, לפעמים context switch מרובים וכו'. במעבדים המוכרים לנו, עיבוד נתונים ב "batch" (ליתר דיוק batch לכל core של המעבד) הוא לרוב יעיל יותר.

הנה class diagram המתאר את PAF בצורה פורמלית:


והנה object diagram שאולי מעט יותר מוחשי לצורך ההבנה:




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

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

למרות המבנה המוגדר-היטב  של PAF, יש עוד מקום רב להחלטות או וריאציות:
  • מהם ה Filters, האם אלו threads בלולאה? האם הם עושים pull מה pipe שמזין אותם או שה pipe עושה push ואולי מספק את ה thread?
  • אולי בכלל מדובר על event loop יחיד לכל המערכת ללא threads?
  • מהם ה pipes? האם הם streams בזיכרון, או אולי פשוט channel של events?
  • כיצד מתמודדים עם concurrency של Filters אקטיביים. כיצד עושים זאת ללא תקורה משמעותית?
  • הגדרת הממשקים בין ה pipes וה filters (במיוחד כאשר רוצים מערכת שניתנת לשינויים בקלות / מאפשרת שימוש חוזר ב filters)
  • כיצד מטפלים ב error handling / מתאוששים מנתונים לא תקניים (מכיוון שהמערכת מחולקת ליחידות בלתי-תלויות - עניין זה הופך למורכב יותר)
  • ועוד


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


ב UNIX / לינוקס משתמשים ב PAF באופן מובנה, בעבודה השוטפת ב Console קרי Bash (או וריאציות דומות).
למשל פקודה בסיסית כמו:

find /var -name "*log*" | grep log

היא בעצם יישום של רעיון ה Pipes and Filters, כאשר התוכנות find ו grep הן המסננים ויש סט של צינורות (pipes) מובנים ב shell.המסננים ביוניקס הם מן הסתם אקטיביים (נוצר תהליך OS process) עבור כל תוכנה ברצף ה PAF. יש מספר pipes זמינים כאשר כל אחר מתנהג מעט אחרת ( | = מעביר עותק כקלט, < = שכתוב, << = הוספה, וכו'). הממשק בין pipe ל filter היא stream של נתונים. ה datasync הוא בד"כ קובץ או פלט על המסך.

Pipes and Filters כפי שמומשו ב Unix. מקור: Ariel Ortiz Ramírez


אפשר לציין גם את כלי ה build שנקרא Gulp, שבנוי בארכיטקטורה של PAF: תהליך ה build הוא בדיוק כזה שאנו רוצים לשנות בקלות ע"י "תפירה מחדש" של ה pipes. את הכתיבה לדיסק (temp files, compilations - למשל כמו שמתרחשת ב Maven או Grunt) מחליפים ב pipes בזיכרון כך ש:
  • לא כותבים לדיסק --> תהליך ה build מהיר יותר.
  • הימנעות מקבצי ה build הזמניים --> אין מה "לנקות" / אין צורך בשלב "clean" = פחות תקלות והתעסקויות.

היתרון של Gulp. מקור: http://slides.com/contra/gulp


דוגמה אחרונה, ומאוד מייצגת היא מערכת / Framework בשם Apache Storm (לשעבר של טוויטר) לביצוע חישובים / ניתוח נתונים בזמן אמת (realtime). האמת, שזה לא ממש realtime (גם אם כמה עשרות ms - זה עדיין לא "realtime") ואני מעדיף לקרוא לה "מערכת לניתוח נתונים ב latency נמוך".

Storm היא סוג של התממשות הסגנון הארכיטקטוני של PAF, ומעט יותר. הוא בעצם מאפשר, בצורה מאוד קלה ומהירה להרים רשת (בטרמינולוגיה של Storm - "טופולוגיה") של pipes and filters ולהריץ אותה מול data sources שונים (מימושים שמגיעים OOTB יכולים להתחבר ל Kerstel, JMS, Redis pubsub וכו'), בעזרת מה שנקרא Spouts (תרגום חופשי: "פיה של ברז") - סוג של Adapter למקור המידע.
אמנם החלוקה ל Pipe ו Filter היא לא בדיוק ע"פ ההגדרה הקלאסית: ה Filter ב Storm (נקרא bolt - בורג) הוא זה שבעצם מגדיר את ה Stream Grouping, להיכן וכיצד להעביר את הפלט שלו (שזה סוג של Pipe). האמת שחיפשתי בגוגל אחר Apache Storm בהקשר של Pipes and Filters - ולא מצאתי שומדבר. האם אני היחידי שרואה את הקשר החזק?!
הממשק של Storm הוא של tuples - רשימות של ערכים (דומה ל HashMap, מפתחות וערכים) אותן מעבדים. כל bolt יכול להמיר את ה tuples, לפלטר אותם (להעביר הלאה רק חלק) או לבצע עליהן סיכומים (למשל: ספירה או ממוצע של הערכים שהוא ראה).

בניגוד ל Bash, למשל, שם ה PAF הוא מקומי וקטן מימדים, טופולוגיה של Storm יכולה להכיל הרבה מאוד nodes, על גבי cluster, שיעסיק הרבה מאוד CPU cores. חלק לא קטן מההתעסקות ב Storm היא התאמה של הטופולוגיה ל cluster שכזה ויישום אופטימיזציות ביצועים / חלוקת משאבים / ניטור ופתרון בעיות וכו'. Storm גם מתמודדת עם נושאים של Fault Tolerance, שאינם חלק מ PAF (דומה בהיבט זה מעט יותר ל Hadoop). שלושת התסריטים הנפוצים לפתור בעזרת Storm הם:
  • Stream Processing - חישוב מתמשך של נתונים המגיעים מ (Stream(s. אולי התסריט הקלאסי ביותר.
  • תסריט של Distributed RPC - לחלוקת עבודה בין מחשבים שונים.
  • Continuous Computation (חישוב מתמשך) - למשל חישוב טרנד שכל רגע משנה כיוון ועצמה, על בסיס stream של נתונים.

אילוסטרציה של טופולוגיה (פשוטה) ב Storm. הקוביות הצהובות הם ה tuples על ה streams. בצד ימין יהיו ה data sync, פעמים רבות יהיה זה  cassandra, או בסיס נתונים דומה.

סיכום


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

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



2014-05-20

תבנית עיצוב: Null Object

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

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

בקורס, אנו מנסים להדגיש את הנקודות החשובות הבאות:
  • תבניות עיצוב כשפה רק עבור התקשורת הפשוטה, כדאי ללמוד תבניות עיצוב: "ה class הזה הוא בעצם כמו Strategy" יכול להגיד המון למי שמכיר את ה Pattern או לגרור דיון של כמה דקות - למי שלא.
  • תבניות עיצוב כתיקון למצב בעייתי, או מה שנקרא Refactoring To Patterns: כדאי ומומלץ להימנע משימוש בתבניות עצוב במחשבה על "מצב עתידי", קרי "יהיה יותר קל לטפל גם במספר רב של אובייקטים אם נשתמש כאן ב Composite". חכו שיהיה מצב בו יש מספר רב של אובייקטים - ורק אז עשו Refactoring ל Composite.
    ההמלצה היא לזהות צורך מיידי ש Pattern יכול לפתור, או לסירוגין smell בקוד שנובע מאי-שימוש ב Pattern ורק אז לעשות refactoring ולהכניס את ה Pattern.

אם "smell" נשמע עבורכם סינית - מדובר על code smells, שהם חלק מהשפה של טכניקת ה refactoring.



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



קצת על null בג'אווהסקריפט


ג'אווהסקריפט הופכת לשפה משמעותית עבורנו - ולכן הדוגמאות שאספק יהיו בעיקר מעולם זה. לא מעניין אתכם javaScript או ה nulls שלה - דלגו ל section הבא.

למה "nulls" ולא "null"? כי יש כמה כאלו בג'אווהסקריפט. תלוי את מי שואלים, יש שניים או שלושה, אני אציג את נקודת המבט המחמירה:
  • יש ערך "null", שמשמעותו היא "נקבע למשתנה זה ערך ריק / חסר משמעות". בניגוד לג'אווה זהו איננו ערך ברירת המחדל למשתנים.
  • יש ערך "undefined" ששמו דיי מבלבל: נשמע שהוא מתאר משתנים שלא הוגדרו - אך בעצם הוא נקבע כערך ברירת מחדל למשתנים שהוגדרו אך לא נקבע להם ערך. שם מוצלח יותר היה יכול להיות unassigned.
  • יש מצב בו לא הוגדר משתנה. אפשר לקרוא לו "בום!": ניסיתם לגשת למשתנה, אפילו בזהירות? - ייזרק error. שם שהייתי מעדיף לכזה משתנה הוא undefined, אבל השם כבר תפוס. זה לא בדיוק null value, אבל הוא דורש התגוננות דומה (ונוספת).

בואו נראה דוגמת קוד:



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


מקור

כלומר: כדי לא לחטוף "NullPointerException" וגם / או "UndefinedPointerException" (בקריצה לג'אווה) האם עלינו לבדוק כל משתנה שאנו מקבלים - פעמיים בפני אפשרות ל null?

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

נראה עקבי.
אבל... מה קורה עם משתנה z שלא הגדרתי (כלומר הוא: truly undefined)? 
בואו ננסה:

אולי סוג אחר של הגנה?



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


אוי ואבוי? האם צריך לעשות בדיקה כזו בכל מקום בקוד?
בכלל לא... ארגומנט של פונקציה תמיד יהיה מוגדר, לפחות undefined.
יש לעשות בדיקה מקיפה זו כל פעם שניגשים (פעם ראשונה?!) למשתנה במרחב הגלובלי.
הערה: גישה למשתנה גלובאלי בצורה  <משהו>.window היא דווקא בטוחה בפני ReferenceError. תודה לקורא שתיקן אותי.

אז האם יש 2 או 3 ערכי null בג'אווהסקריפט? 
  • אולי אלו 2: null ו undefined
  • אולי אלו 2: null/undefined ו truly undefined
  • אולי אלו 3.
 תלוי את מי שואלים....







מה הבעיה עם null?


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

מה הבעיה עם null?
איזה Exception מעיף לכם את התוכנה, בשפה ה strongly types עם הקומפיילר ההדוק שלה (קרי: Java), הכי הרבה פעמים?
רגע... תנו לי לנחש (לתקשר) ... האם זה אולי NullPointerException?

כשאנו מפעילים פונקציה (/מתודה) ורשום לנו שהפונקציה מחזירה אובייקט מסוג ListItem, בעצם זה נכון נכון: היא מחזירה אובייקט מסוג ListItem או null.
כשרשום שהפונקציה מחזירה אובייקט מסוג List, גם זה לא נכון! היא מחזירה אובייקט מסוג List או null.

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

אם כ"כ הרבה מפתחים שוכחים אותו דבר - כל כך הרבה פעמים, אולי הבעיה היא בשפה / כלים ולא במתכנתים?!


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

הנה דוגמה מקוד של jQuery, ספרייה שעפו בה המון referenceErrors לאורך פיתוחה. באופן כמעט אקראי בחרתי בפונקציה add שרושמת אירוע על אלמנט בדום בעקבות קריאה ל (...)on.$. היא לא מקבלת את הפרמטרים כמו שהם - פונקציית on עושה המון בדיקות קלט, כולל nulls למיניהם. שימו לב עדיין מה יש בה:


סימנתי בצהוב כל מיני בדיקות null למיניהן שעדיין יש לעשות, למרות ההגנה של פונקציית on.
מה זה?? האם jQuery הוסיפה טיפוס null משלה בשם "strundefined"? 
לא לדאוג. זהו פשוט קיצור של "typeof undefined" - כנראה בגלל שיש הרבה בדיקות כאלו.

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



"מראה מראה שעל הקיר, מי השפה עם ה Null המזיק-פחות, שאותו יש להוקיר?"
מקור: הבלוג הטכני של לוסידצ'ארטס https://www.lucidchart.com/techblog/



מה עושים?


וואהו! הצלחתי למלא את הפוסט דיי מהר, ובלי לשים לב. ככה זה ארכיטקטים: דברנים!
ישנן שפות מעטות (ואמיצות!) שהחליטו להיפטר מ null. אני שמעתי על Cyclone (דיי נדירה) ועל Haskell [א].
הייתי פעם בהרצאה של מישהו שהציע תחביר בו מצב ברירת המחדל הוא שאובייקט לא יכול להיות null. אם פונקציה יכולה להחזיר null, חובה עליה להכריז על ערך ההחזרה עם prefix של סימן-שאלה (כמו nullable object ב #C). למשל: 

public ?ListItem getChild(....);

או

private ?List calcItems(...);


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

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

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

class Employee {

  public final static NULL_EMPLOYEE = new Person('<none>', [], 0, '<empty record>');

  Employee (String name, String[] expertise, int age, String desc) {
        …
  }
}

הרעיון הוא שבמקום להחזיר null, אני אחזיר את Employee.NULL_EMPLOYEE, שתאפשר לקוד להמשיך לרוץ - מבלי לשבור אותו.

אם יש לולאה שרצה על מערך מומחיויות העובד - ריצה על מערך ריק (שמגיע מה null object) לא תשבור אותו, אין בעיה. הקוד ימשיך בד"כ gracefully. פה ושם יהיו מסכים מוזרים שמדברים על עובד ששמו "<none>" - אך זה הרבה יותר טוב מהודעת שגיאה לא ברורה, והמתנה ל patch הקרוב.

את תבנית העיצוב של Null Object מתארים באופן פורמאלי בצורה הבאה:


מקור: AndyPatterns

אפשר בהחלט לא להשתמש ב Null Object אחד בעל משמעות כללית, אלא לייצר כמה, עם משמעות סמנטית עשירה יותר, ועם התנהגויות שמתארות בצורה טובה יותר את ה "null behavior" (או "do nothing") של אותו האובייקט. למשל במערכת העובדים:



פתרון אחר, אולי "פתרון חצי-דרך", הוא בשלב מוקדם ככל האפשר - להחליף ערכי null בערכים סבירים אחרים - עבור שאר ה flow. זכרו שאם בדקתם בפני null נקודתית אז פתרתם את הבעיה של היום, אבל לא את התיקון / תוספת של "עוד-שעה". פתרון זה (שאני קורא לו "inline null object") הוא לא אידאלי, אבל מהיר וקצת יותר ארוך טווח מטיפול נקודתי ב null. כמו פלסטר עם דבק חזק במיוחד.

הוא נראה כך (בכתיבה המקוצרת שלו בג'אווהסקריפט):


init: function(options) {
    this.user = options.user | { name: “unkown”, items: []};
},


עדכון יוני 2014:

אפל הודיעה על שפת Swift, שתחליף עם הזמן את Objective-C לפיתוח OS X/iOS ומה שאומר שצפוי לה שימוש נרחב. מה הקשר? ב Swift משתנים לא יכולים להיות nil אלא אם הוגדרו כ Option Type (מה שנקרא גם "Maybe") - שבתחביר השפה זהו סימן שאלה בסוף - למשל ?Int. פתרון מאוד אלגנטי לטעמי לעניין ה null!
התחביר דוגמה מאוד ל nullable types ב #C - תחביר המאפשר nulls ב primitives. כלומר - עשו שם רק את החצי הקל של העבודה...


סיכום 

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


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


----

[א] יש לה משהו שנקרא maybe שאמור לטפל בצורה פשוטה במקרים לא צפויים. אני לא יודע איך הוא בדיוק עובד.



2014-05-09

בלוג ארכיטקטורת תוכנה בפייסבוק

Google Reader מת. כבר מזמן, בעצם.

חלק נכבד מהקוראים של הבלוג (כ 500 בערך) עקבו אחריו מתוך Google Reader.
כש Google Reader נסגר הייתה ירידה משמעותית בפעילות על ערוץ ה RSS (אני מקבל נתונים עליה מתוך שירות של גוגל שנקרא feedburner). אנשים נכנסים הרבה מאוד מ "direct link" מה שאומר שכנראה שיש להם bookmark שהם בודקים מדי פעם...

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





כבר מאז אני חושב לפתוח עמוד פייסבוק, אז עכשיו באיחור (אופנתי במיוחד) - זה קורה.
בעמוד הפייסבוק: (https://www.facebook.com/pages/Software-Architecture-Blog/793262500685552)
  • אפרסם את הפוסטים החדשים מיד לאחר שאשחרר אותם בבלוג. אני מניח שעבור קוראים רבים דרך זו תהיה נוחה מהערוצים הקיימים. 
  • אעבור על הפוסטים הישנים ואפרסם כמה מהם שנראים לי מעניינים וייתכן שחלק מהקוראים פספסו.
  • אולי אפרסם לינקים אחרים - אם אחשוב שהם ממש מעניינים.
אני מודה שיותר מעניין אותי להשקיע בכתיבה מאשר בהנגשה של התוכן, אחרת הייתי עושה זאת כבר מזמן...
את ערוץ המייל, אגב, פתחתי עבור אשתי - שקצת התעניינה על מה אני יושב כ"כ הרבה שעות, אולם מאז (להפתעתי) יש לו מספר לא מבוטל של משתמשים.

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


ליאור


2014-05-03

דעה: 5 תחומי-המומחיות ש"עושים" ארכיטקט

מקצוע ארכיטקט התוכנה הוא מקצוע שאינו מוגדר בצורה טובה. רק חשבו על הווריאציות הרבות (או השמות השונים) של התפקיד:
  • Development architect
  • System architect
  • Enterprise Architect
  • Solution architect
  • Application Architect
  • Integration architect
  • Data architect
האם מישהו יכול לומר מה ההבדל בין התפקידים הנ״ל בצורה ברורה?
האם מישהו יכול לתת לאחד התפקידים הנ״ל הגדרה מעשית ויציבה?

חוסר בהירות - הוא כנראה חלק מהתפקיד.


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

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

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






מומחיות מספר 1: מומחיות טכנולוגית


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

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

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

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

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

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

מדד מעניין לידע "Architect-like" הוא היחס בין "מה שאני יודע שאיני יודע" (בקיצור: "לא.יודע") לבין "מה שאני לא-יודע שאיני יודע" (בקיצור: "אין.מושג").

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

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


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


עוד דבר שיש להיזהר ממנו, הוא הצמדות ל stack (או "ארגז כלים") יחיד של טכנולוגיות. כאשר מתמחים ב JEE, ניתן להאמין שהפתרון הנכון לכל בעיה הוא איזו "דרך של JEE". אפשר כנראה לפתור הכל בעזרת JEE - אבל זה לא כ"כ יעיל. דוגמאות נוספות:
  • SQL ו noSQL
  • Open Source ו Commercial Software
  • שפות typed (כמו ג'אווה או ++C) ושפות דינאמיות (Python או javaScript)
  • ארכיטקטורת מונחית Data / שירותים וארכיטקטורה של components או Object-Oriented.
  • UI צד-לקוח, UI צד-שרת או Desktop UI [א]
קיים יתרון אמיתי לארכיטקט ש"מאמין" ביכולת לפתור בעיות ב-2 האלטרנטיבות, ארכיטקט שאינו "משוחד" לפתרון מסוג מסוים.
אמנם לא קל להגיע למצב שמכירים, ומאמינים (להכיר בכדי לנגח - זה לא מספיק) שני צדדים ויותר - ובמספר תחומים.
זוהי שאיפה ארוכת-טווח.

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


"הכל זה trade-offs" -- משפט של ארכיטקטים.




מומחיות מספר 2: תקשורתיות טכנית


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

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


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

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

סוגי ארכיטקטים שונים, כחומרים מגשרים בין גופים שונים.

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







מומחיות מספר 3: תקשורתיות אנושית והנעת אנשים


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

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

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

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

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

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

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

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

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


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




מקור התמונה


מומחיות מספר 4: Domain knowledge


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

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

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

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


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

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

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






מומחיות מספר 5: כלים של "ארכיטקטורת תוכנה"


המומחיות האחרונה: כל אותם כלים טכניים שנועדו להתמודד עם מערכות גדולות ומורכבות:
  • מערכות של עקרונות הנדסת תוכנה כגון SOLID או GRASP. [כתבתי עליהן קצת בפוסט הזה, ובאופן עקיף גם בפוסט ההוא]
  • UML/sysML - שפות לתיאור פשוט של מערכות (מורכבות).
  • Quality Attributes - כלי להבנת ה non-function requirements של המערכת [כתבתי עליו בפוסט הזה]
  • ATAM - כלי להבחנה בין Trade-offs בהם נעשה שימוש במערכת.
  • "Architecture Styles" ו "Architectural Patterns" (שלעתים עושים יותר נזק מתועלת). הם שימושיים לתקשורת יעילה יותר בין אלו שמכירים אותם.
  • עוד כמה כלים... שאני פשוט לא מאמין בהם: למשל CBAM או Architectural Views אדוקים - שמעולם לא סייעו לי.
  • מתודולוגיה: סקראם, Lean Startup או Continuous Delivery. לא רק עניינם של ארכיטקטים, אבל גם. 
  • הרבה Buzz words ותחכומים - להתחבא מאחוריהם.
חלק מהכלים (ATAM, Quality Attributes) - לא מוכרים למתכנתים, אפילו לא למתכנתים הותיקים והמנוסים.
כלים אלו יכולים לסייע בתכנון של מערכות גדולות ומורכבות, וטוב שיהיה מישהו בארגון שמסוגל להתבונן בפרספקטיבה הזו ולהשתמש בה.

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




קטרוג: "לא צריכים ארכיטקט"


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


"מדוע עדיף שלא יהיה ארכיטקט"

ביקורת לא כ"כ מבוססת או עניינית:
  1. ארכיטקט, כהגדרה, הוא לא מעודכן בטכנולוגיה. כשהוא היה היה מתכנת, COBOL (או ג'אווה - אולי "הקובול הבא") הייתה השפה - ועכשיו הכל אחרת והוא לא מבין שומדבר.
  2. ארכיטקט רק אוהב לצייר ריבועים ולסבך מערכות. הוא מזיק ולא תורם. דיי כבר עם SOA, MDA, EJB או Software Factories!
  3. ארכיטקטים עסוקים בליצר Job Security ולדאוג שכולם יהיו תלויים בהם - ובדרך רק עושים נזק.
לא שאין ארכיטקטים כאלו: פשוט תעמידו אותם במקום או אל תעסיקו אותם. זה לא טיעון רציני כנגד רעיון הארכיטקט ככלל. 


ביקורת יותר עניינית:
  1. עצם קיומו של ארכיטקט, פוגע בעצמאות של המתכנתים: אם זה מישהו להישען עליו בפתרונות טכנולוגיים או קבלת החלטות, ואם בהבנת התמונה המלאה של כלל-המערכת. 
  2. ארכיטקט שלא ממש חי את הקוד, אפילו אם הוא מבין פחות או יותר את הטכנולוגיה, עלול להוביל את המתכנתים למקומות לא נכונים. רק הבנה מלאה בפרטים - מספיקה כדי לקחת החלטות שמשפיעות על הקוד.
  3. ארכיטקט הוא לא גוף ביצועי (לפחות לא כמו מתכנתים) - ולכן הוא יכול להרשות לעצמו להטיל ביקורת על המבצעים ללא היכר. התוצאה: ניכור ומורל נמוך בקרב המתכנתים - שיוצר יותר נזק מסה"כ התועלת של הארכיטקט.
  4. ארכיטקט, מעצם קיומו או תפקידו, יכול לייצר מתח נוסף בקרב המפתחים ו / או אנשי המוצר (גם QA, Performance וכו'). חבל.
  5. כשהארכיטקט הופך להיות middleman - הוא יוצר שכבה מיותרת ומסרבלת של תהליכי הפיתוח.

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

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



סיכום


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

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

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


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



----

[א] המקבילה המודרנית של Desktop UI היא native mobile app.

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

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