Techkiz – לחשוף סטודנטים לעולם

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

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

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

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

מפגש הפתיחה של הקורס, במעבדות סאפ

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

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

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

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

  • איך מתפקדת חברת תוכנה
  • איך מוכרים תוכנה
  • מערכות ווב
  • בסיסי נתונים
  • טכנולוגיות ענן
  • מתודולוגיות פיתוח
  • תהליכי תוכנה (build, delivery, version control וכו')
  • איך להתמודד עם ראיונות עבודה
  • ניהול קריירה
  • יזמות
  • וכו'
בתקופה של כשבוע (כ 30 שעות נטו) לא ניתן באמת ללמד חומר משמעותי, אבל ניתן לחשוף את הסטודנטים למציאות / רעיונות / ידע – שישנה את תמונת עולמם. חשיפה שאנו מקווים שתסייע להם לספוג יותר מהתואר – ולהבין כיצד הנושאים בהם הם נתקלים בתואר מתחברים לכדי מציאות שלמה. בנוסף, גם לחשוף אותם לכל מיני היבטים שאליהם הם לא ייחשפו בתואר – אבל חשוב שידעו שהם שם, כחלק מהתמונה השלמה.
אני סיימתי את התואר שלי לפני 11 שנה בערך. העולם המקצועי השתנה לא מעט, ואני מקווה שהתארים גם השתנו – בהתאם [א]. גם המדיה ואמצעי הלמידה השתנו – ונראה לי שסטודנטים של היום הרבה יותר מודעים למה שמתרחש סביבה (כמעט כולם שמעו על Big Data, ענן או Hadoop. מעטים מאוד הבינו במה מדובר)
בימי, הדרכים הכי טובות שמצאתי להתעדכן במה שמתרחש בעולם היה לשוטט בספריה בחיפוש אחרי ספרים חדשים, לקרוא PC Magazine (האא… הוא חוזר על עצמו מתישהו), או לקרוא בצמא את c2 wiki.
היום יש את Hacker News, גיקטיים, StackOverflow וכו' – שהרבה יותר סטודנטים נחשפים אליהם מאלו שנחשפו למקורות שלי – בזמני. בעצם: נראה לי שאני הייתי היחידי, במחלקה אם לא באוניברסיטה :).
אחוז הסטודנטים שעובדים, או שעושים "פרויקטים אישיים בצד" גם הוא נראה לי, בהתרשמות מהירה, גבוה בהרבה ממה שהיה מקובל בזמני.
טוב שכך.
בכל מקרה, נראה לי שהחשיפה לה זכו הסטודנטים בקורס שלנו הייתה משמעותית מאוד. דיי שוק, אני מתאר לעצמי. שוק חיובי.
הכוונה, להזכיר, היא שסטודנטים יתחילו להתבונן על החומר באוניברסיטה קצת אחרת, ולקשר קצת לאלו תחומים ושימושים – כל ידע שייך.
מחזור או שניים בשנה של 40 סטודנטים הוא שינוי מוגבל, אולם התקווה שלנו היא שארגונים אחרים ילכו בעקבותינו, יציעו קורסים דומים, ומספר הסטודנטים שיוכלו להיחשף לתכנית מסוג שכזה יגיע לכמה מאות בכל שנה.
אני אישית העברתי כמה הרצאות:
ארכיטקטורת תוכנה + ארכיטקטורה של מערכות ווב (לבסוף איחדתי את 2 ההרצאות להרצאה אחת ארוכה).
שם ליווינו סיפור דמיוני על אתר מהפכני שתכננתי, בשם "ספר-פנים", שמתחיל כקובץ HTML פשוט, אך גדל בהדרגה להיות אפליקציית ווב, ואח"כ מערכת ווב שלמה (בסיס נתונים, Load Balancer, multi-tier Architecture, צד שרת וצד לקוח, וכ'ו).
שפות תכנות של העולם 
הרצאה זו הייתה תחליף של הרגע האחרון לסשן של פיתוח אנדרואיד – בו המרצה המקורי גוייס למערכה בעזה.
בהרצה זו הצגתי את הייחודיות והשימושים של 4 שפות תכנות שונות מהעולם האמיתי:
ג'אווהסקריפט, פייטון, גו, וסוויפט (Swift – החדשה של אפל). לרוב הסטודנטים כל ארבעת השפות היו חדשות.
מתודולוגיות פיתוח
שם הצגתי כיצד עבדו פעם (Waterfall, בעצם משהו יותר כמו RUP) ואיך עובדים בסקראם (תמונות מחיי היומיום).
אח"כ חזרתי לשורשים הפילוסופיים של כל זן מתודולוגיות (טיילור ל RUP ו TPS של טויוטה ל Agile) – והעקרונות / רעיונות שעומדים מאחוריהן.
לבסוף סקרתי כמה פרקטיקות מ 3 מתודולוגיות אג'יליות מודרניות: XP, סקראם ו Lean Startup.
זהו.
היה דיי מרגש. אני חושב שזה היה קורס טוב, למרות שבטוח שיש גם מה לשפר.
היה מאוד מעניין אותי לשאול את הסטודנטים שעברו את הקורס, ברטרוספקטיבה של חצי-שנה שנה – איך החוויה שלהם מקורס כזה לאורך זמן. אולי אנסה לארגן סקר שכזה.
ליאור
—-
—-
[א] קיבלתי לעיון את כל חומר הלימודים מסטודנט שיסיים לאחרונה תואר זהה לשלי – והשינוי שם היה דיי מתון. אני חושב שרוב הקורסים לא השתנו משמעותית (עדכונים קלים בלבד), וגם התכנית בכלל – רק השתנתה במעט. 11 שנה בעולם התוכנה – זה דור.

דעה: איך להתקדם בארגונים?

הפוסט הבא, הוא פוסט לא כ"כ שגרתי בבלוג: הוא עוסק יותר בניהול מאשר בטכנולוגיה או ארכיטקטורה.

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

על בסיס איזו מומחיות אני כותב את הפוסט?

  • לתפקיד הראשון שלי (ארכיטקט) התקדמתי דיי מהר – פחות מ 4 שנים בתעשייה. מאז קצת יותר לאט 🙂
  • בעיקר בתור צופה, שעובד עם הרבה אנשים וצוותים – וחווה את הדינמיקות הארגוניות כבר שנים.
    בהקצנה: כפי שניקולו מקיאוולי כתב על משילות, למרות שמעולם לא שלט בעצמו.
  • על בסיס 2 ה Reviewers שלי לפוסט, בעלי הניסיון הרב הנושא: אליאל שורמן (מנהל קבוצת פיתוח ב SAP) ונמרוד ברק (דירקטור פיתוח ב SAP) אשר קראו, הוסיפו, ותרמו באמת לפוסט. תודה רבה אליאל ונמרוד!
נושא זה כמובן מאוד סובייקטיבי – וכולם מוזמנים להגיב. אנא נסו לעשות זאת בצורה עניינית – ולא רק לשם ההתרסה.
תיאום ציפיות קצר: אל תצפו לקסמים.
לא כל אחד אכן יתקדם תפקיד, ולא בכל ארגון. הפוסט הזה לא "טריק" שיבטיח קידום מהיר. הפוסט, בשאיפה, יכול לעזור – אך הוא לא ייצר מציאות חדשה.
כמו כן, אין שום הבטחה שקידום (למרות שהוא בד"כ יעד נכסף) יבטיח לכם אושר. אולי אפילו להיפך: הלחץ, האחריות והתחרות הגבוהה בעמדות הגבוהות – לא תמיד מפצים (מבחינת "מידת האושר") על המעמד, הכסף, או העניין שמגיעים עם התפקיד. כבני אדם, אנו חווים את הצלחתנו יחסית לסביבה המקבילה לנו – ובכדי להיות מאושרים עדיף לנו להיות "ראש לשועלים" (נאמר: "מתכנת תותח") על פני זנב לאריות (למשל: "ראש צוות בינוני").
לחיוב, אציין שחווית הקידום (במיוחד הראשונה) תורמת רבות להבנת העולם בו אנו חיים. למרות שארגונים רבים מנסים לגרום למפתחים להיות מיודעים, סוג המידע והחשיפה שמגיע למנהל זוטר הוא שונה מהותית מזה שמגיע למפתח. אין כמו להיות שם בכדי להבין את הדינמיקות הארגוניות, המוצריות והאנושיות שמתרחשות מסביב.
ייתכן ואפילו משתלם להיות "ראש צוות בינוני" כמה שנים – בכדי לחזור להיות "מתכנת תותח" שגם מבין טוב יותר את הארגון. אני מניח שזה עניין אינדיבידואלי, כמובן.

המודל הבסיסי

אני לא מכיר שום מודל קיים בנושא, ולכן אגדיר אחד:

קידום מתבצע כאשר מתקיימים 3 תנאים:

  1. יש משרה פנויה מתאימה.
  2. הקרדיט שלכם מספיק גבוה כדי שהמנהלים בארגון יראו בכם אופציה רצינית לאיוש המשרה.
  3. מבין המתמודדים הפוטנציאלים – אתם המועדפים. לא מדובר רק להיות מועדף על המנהל המגייס, אלא להיות סוג של קונצנזוס בקרב ה peers כך שהמנהל המגייס לא יאלץ להצטדק ולהסביר מדוע עשה את הבחירה.

על תנאים 1 ו 3 – אין לכם הרבה שליטה. זה עניין של סבלנות, הזדמנות, ומזל.
תנאי מס' 2 – הוא כולו באחריותכם.

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

הקרדיט בעצם בנוי מ-2 מרכיבים עיקריים:

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

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

הקרדיט הכולל שלכם מנוהל בכמה "חשבונות" בצורה מצרפית:

  • חשבון "המנהל[ב] הישיר שלכם" – שזה החשבון הפעיל והחשוב ביותר.
  • חשבון "העובדים המקבילים לכם (peers)" – אלו שעובדים אתכם בצוות, או עובדים אתכם על אותן המשימות.
  • חשבון "המנהל של המנהל שלכם + מנהלים אחרים בארגון (ההנהלה)" – שניזונים במידע אודותיכם מהעובדים שלהם, מהמנהל שלכם ואחד משני. שלא תטעו במחשבה שהם לא מכירים אתכם: לכל אחד, כמעט, יש אצלם חשבון.

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

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

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

"הישרדות": אל תיקחו משם רעיונות, אלא אם אתם מתכננים לחזור הביתה לאחר 3 חודשים…

טקטיקות נפוצות לקבלת קידום – וניתוחן ע"פ המודל

הנה טקטיקות נפוצות בהן ראיתי שאנשים משתמשים – וניתוח היעילות שלהן:

"לעשות שרירים" (bully) על חברים לצוות – שכולם ידעו שאתם הכי דומיננטיים בצוות
שורף (מפחית) לכם קרדיט אצל ה peers, ולא כ"כ סביר שייצור איזשהו קרדיט חיובי אצל מנהלים אחרים.
בקיצור: להימנע!

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

בקיצור: טקטיקה שנויה במחלוקת.

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

אכפתיות והפתעה לטובה
לעשות דברים קטנים שלא מבקשים מכם, ולהיות אכפתיים יכולים לייצר לכם הרבה קרדיט חיובי.
דוגמה אישית 1: פעם בכל התקנה של מכונה אצלנו, היה צריך לקחת template של XML ולמלא אותו עם פרטי המכונה ולזרוק באיזו תיקיה. כמתכנת – כתבתי servlet שמייצר את ה XML אוטומטית בזמן ריצה ושיניתי את הקוד שיקרא את ה servlet ולא את הקובץ בדיסק. זו הייתה עבודת תכנות קטנה מאוד – אבל שיצרה לי המון קרדיט בקרב peers ומנהלים.
דוגמה אישית 2: בחברה אחרת, היו במטבח 4 קופסאות עוגיות אטומות, שכל יום שמו בהן חטיפים אחרים. כן, עוגיות. כל מי שבא להפסקת קפה היה פותח את כל הארבעה אחת אחרי השנייה – בכדי לבדוק מה המבחר באותו הרגע. זה היה טקס מציק – אך כולם עשו אותו מבלי לשים לב. ביקשתי תקציב וקניתי 4 קופסאות שקופות – והפעולה הקטנה הזו יצרה לי יותר קרדיט מהרבה עשייה מורכבת וקשה יותר. היא לא הייתה קשורה לתוכנה, אבל היא נגעה לכולם והפגינה אכפתיות.

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

walk the walk, talk the talk
להתחיל לבוא לעבודה בנעליים מצוחצחות וחולצה מכפותרת, להתנהג "כמו מנהל" (למשל: לחקות את סגנון הדיבור המקובל – בד"כ צבאי משהו).מצד אחד – למנהלים, ואולי לעובדים יהיה יותר קל לדמיין אתכם כ"מנהלים".
מצד שני – על מי אתם עובדים? האפקט יכול לפוג במהרה. ואיפה בדיוק צברתם קרדיט?אני מניח שגישה זו תגרום לכם לקבל קצת יותר תשומת לב, ושיבחנו אתכם יותר – אך לא נראה לי שהיא משפרת עקרונית את מעמדכם. ראיתי אנשים זרוקים ביותר – שקודמו למשרות ניהול (ורק אז התחילו לבוא עם… כפכפים אלגנטיים יותר).
אני מניח שיש סיבה שלביטוי הזה אין מקבילה בעברית – זה פחות משנה בישראל.

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

בקיצור: אפקטיבי רק כאשר יש לכם קרדיט משמעותי.

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

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

בקיצור: להימנע! זוהי טקטיקה יעילה רק בדבר אחד: למנוע מעצמכם קידום.

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

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

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

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

בקיצור: לא מספיק טוב.

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

חשבו גם על המנהל של המנהל שלכם: האם הוא יעדיף לנהל מישהו שמוציא את מנהלו טוב, או רע? – נחשו לבד.

בקיצור: טקטיקת בסיס חשובה.

אבני דרך חשובות

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

צרו לעצמכם הזדמנויות לקבל "קרדיט ניהולי"

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

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

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

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

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

בכל מקרה – כבדו את אסטרטגיה של הארגון

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

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

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

אלו רגשות אנושיים וטבעיים, אבל כאשר אתם מפגינים אותם בין כותלי הארגון – זו בעיה.

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

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

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

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

הפגינו מחויבות לארגון

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

כיצד נמדדת מחויבות לארגון?

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

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

אור הזרקורים

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

תכונות עצמיות להן כדאי לשים לב

נראות

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

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

להבין את רמת הנהילות שלכם

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

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

לפעמים עובדים לא מבינים מדוע מישהו אחר בצוות מקבל יחס מסוים (יכול לעבוד מהבית / לבחור לעצמו משימות / משהו נחמד אחר) – והם לא. לרוב הסיבה נעוצה בכך שאותו אדם נמצא במאזן חיובי של מה שהוא תורם – למה שהוא "עולה" למנהל.

Troubleshooting

מנהל לא-טוב

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

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

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

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

המנהל אומר לי שאני מתאים, אך כבר זמן מה לא קורה שום דבר

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

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

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

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

סיכום

עבודה טובה היא לא קרדיט,
קרדיט הוא לא מוכנות לקידום,
מוכנות לקידום היא לא קידום,
קידום הוא לא אושר

כל עוד אתם זוכרים זאת – אזי הכל בסדר 🙂

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

לאן אשר תלכו – שיהיה בהצלחה!

—-

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

[ב] או מנהלת, כמובן.

להבין Maven (הצצה ראשונית)

מייבן (Maven, מלשון \"מבין\" ביידיש) היא ספריית build ו dependency management לסביבת ה JVM, וג\'אווה בפרט.

מייבן איננה חדשה, והיא איננה הטרנד החם בתחום – אך היא עדיין נפוצה מאוד. ע\"פ סקר מ 2013 – כ 70% ממפתחי הג\'אווה משתמשים בה.

אמנם ל Gradle (ספרייה מתחרה, שהיא הטרנד החם בתחום) יש כמה יתרונות מובנים על פני מייבן (קלות תחזוקה: DSL מול XML + מהירות ריצה) – אבל ייקח עוד זמן עד שהיא תוכל להחליף את מייבן: ל Gradle אין עדיין repositories משלה, וכמות ה plugins הזמינים עבורה – נמוכה בהרבה. היא גם מתבססת על Groovy – שפה עם קהילה לא כ\"כ גדולה [א].

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

בואו נתבונן לרגע על מרחב הכלים הקיים.

יש כמה וכמה כלי Build נפוצים:

  • Make של C או ++C ו Unix (שנת 1977)
  • Ant של ג\'אווה (שנת 2000)
  • מייבן של ג\'אווה (שנת 2002)
  • Rake של רובי (לא יודע ממתי בדיוק)
  • SBT – קיצור של Simple Build Tool, של סקאלה (שנת 2008)
  • Gradle לג\'אווה / גרובי (שנת 2012)
  • Grunt ו Gulp לג\'ווהסקריפט (חדשות למדי).
ויש גם כמה כלים לניהול תלויות:
  • מייבן – הכוללת גם כלי ניהול תלויות. אולי הראשון מסוגו.
  • Ivy (שנת 2007) – קיימת כתת פרויקט של Ant, אך יש לה זכות קיום עצמאית. משמשת את SBT ואולי גם כלים אחרים.
  • Gradle – התחילה כתלויה ב Ivy, אך פיתחה עם הזמן מערכת ניהול תלויות עצמאית.
מערכות לניהול תלויות הן מערכות דומות מאוד ל package managers, כמו אלו של לינוקס, npm של node.js, או bower של ספריות ג\'אווהסקריפט. ההבדל הוא שהן מנהלות source code ולא code ל production (כך שאין צורך לבצע התקנה), ושיש להן אינטגרציה לכלי build: כאשר ב build מסומנת תלות בספרייה שלא קיימת – כלי ה build יוריד אותה בצורה אוטומטית, כך שה build יוכל להסתיים בהצלחה.

מה מייבן מספקת, ובמה היא טובה מ Ant?

קרן Apache מנהלת גם את Ant וגם את Maven. מדוע לנהל 2 ספריות מתחרות? מה מייבן (המאוחרת יותר) מנסה לעשות ש Ant לא עשתה?

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

לסקריפט (קובץ build.xml, במקרה של Ant) יש כמה יעדים (Targets / Goals) שנקראים לרוב משהו כמו: build, clean, jar ו test – כ\"א הוא תיאור של סדר הפעולות האטומיות (העתקת קבצים, קומפילציה וכו\') הנדרש להשגת מטרה זו. בין ה targets השונים ניתן להגדיר תלות, כך שהפעלת אחד (למשל: אריזה ב jar) – תפעיל גם את התהליך בו היא תלויה (למשל: compile). מנגנון התלויות בין ה targets מאפשר לנו לעשות שימוש חוזר בסקריפט ה compile גם ב targets כמו jar או install.

תכונה שימושית נוספת ב Ant היא הגדרה של משתנים – המאפשרים לשנות במקום אחד פרמטר (כמו path מסוים) – ולהשפיע על כל הסקריפט.

דוגמה ל Ant Task פשוטה

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

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

  • יש לקמפל את קבצי ה java לקבצי class ולשים אותם בתיקיה זמנית.
  • מקמפלים ומריצים את הקוד של בדיקות היחידה.
  • במידה והבדיקות עברו בהצלחה – בונים jar או war.
  • מנקים את הקבצים הזמניים שנוצרו.
מדוע לכתוב את ה Script הזה כל פעם מחדש? האם האנושות לא יכולה לחסוך לעצמה את \"המצאת גלגל ה build\" – בכל פעם מחדש?

מייבן מספקת Archetypes (מעין templates) של פרויקטים נפוצים: פרויקט jar, פרויקט ווב, פרויקט ווב של backbone וכו\'. שימוש ב Archetypes חוסכת הן עבודת קידוד והן עבודת תכנון – כיצד להרכיב את פרויקט ה build, באיזה מבנות תיקיות להשתמש וכו\'.

ה Archetypes לא קיימים באוויר (ואין להם חופש פעולה מלא) – הם מצייתים למודל מובנה של מייבן שמתאר תהליך של build. המודל מחלק את תהליך ה build לכ 20 שלבים סטנדרטיים, וכל archetype מגדיר את עצמו בתוך המודל הגנרי של מייבן.

כל פעולות ה build עצמן (יצירת תיקיות, העתקת קבצים, הפעלת קומפיילר וכו\') מגיעות כ Plugins – וניתנים להחלפה. מייבן מספקת את המודל, קובץ הקונפיגורציה של מייבן מתאר את ה Strategy (ה design pattern), וה plugins עושים את העבודה.

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

מרגע שמבנה הפרויקט ידוע וקבוע – ניתן לספק הוראות הרבה יותר high level מאשר ב Ant: \"בצע קומפילציה\" במקום \"צור תיקיה זמנית x\", \"הפעל את javac עם target של x\", \"העבר קבצים מתיקיה x לתיקיה y\", וכו\'.

פרויקט פשוט במייבן

יצירת פרויקט של מייבן מתוך Archetype (להזכיר: סוג של template של פרוייקט) יכולה להיעשות בעזרת command line, אבל בפועל כיום יש אינטגרציה לכל IDE נפוץ – כך שאין כ\"כ צורך להכיר את ה command line. הבה נבחן את מבנה התיקיות של הפרויקט הגנרי של מייבן:

כמה הסברים:

  • תיקיית src נועדה לקוד, ותיקיית target לתוצרי קומפילציה (קבצי class., למשל). 
  • תיקיית ה src/main נועדה לקוד שמיועד לדילוור, ותחתיה יש תיקיה לכל שפת תכנות. יכולה להיות, למשל, תיקיה ל java, ל scala ול javaScript. ספריית ה src/test נועדה לקוד של בדיקות יחידה / אינטגרציה. בפנים יש תיקיות של ה java packages – כמו בכל פרויקט java רגיל.
  • תיקיית src/main/resources/ נועדה לקבצים אחרים של הפרויקט שאינם קוד, למשל קבצי הקונפיגורציה של Spring Framework.
  • את תיקיית ה target מחלקים לתוצרים של קוד שהולך לדילוור (classes) ותיקיית הקוד שלא הולך לדלוור (test-classes).
  • pom.xml הוא קובץ הקונפיגורציה של מייבן, המקבילה של build.xml של Ant.

קובץ ה pom.xml (קיצור של Project Object Model) הוא קובץ XML, דקלרטיבי, שמגדיר את ה Strategy של תהליך ה build שלנו.

הנה דוגמה ל pom.xml מינימלי ביותר:

הסברים:

  1. כל פרויקט מייבן מוגדר באופן ייחודי ע\"י שלושה פרמטרים:
    1. groupId – סוג של namespace שאמור להיות globally unique. בד\"כ כתובת אתר האינטרנט של החברה שלכם בסדר הפוך של tokens.
    2. artifactId – שם ייחודי, פנימי אצלכם, לפרויקט.
    3. מספר גרסה, בפורמט: ..-, כאשר ה qualifier הוא טקסט [ב].
      ל qualifier בשם \"SNAPSHOT\" (אותיות גדולות) – יש משמעות מיוחדת, והיא משמשת לציין גרסה שעדיין בפיתוח שמשתנה כל הזמן. במקום לבדוק אם הגרסה התעדכנה בעזרת מספר הגרסה, הוא יבדוק את התאריך, כך שהמפתח לא נדרש לשנות כל רגע מספר גרסה בכדי שחבריו יקבלו גרסה עדכנית בכל build.
  2. הגדרה של תלות בספריה JUnit. כ default קיבלנו את גרסה 3.8.1 – אך אנו יכולים להחליט שאנו רוצים לעבוד עם JUnit 4. שימו לב שגם ספרייה זו מזוהה בעזרת השילוש הקדוש: קבוצה, artifact וגרסה. זהו הזיהוי הייחודי ב repositories של מייבן.
  3. זוהי תצוגת ה IDE למייבן של IntelliJ – בכל IDE יהיה משהו שנראה אחרת. אנו רואים את השלבים המרכזיים בתהליך הבילד כפי שהוגדר.
שנייה! לא הגדרנו כמעט כלום בקובץ ה pom.xml שלנו. מאיפה מגיעות ההגדרות הללו?
אם אנסה להריץ אחד השלבים, למשל test, מייבן יוריד לי ערמה של maven plugins הנדרשים להרצה – ויריץ קומפילציה ובדיקות בהצלחה. כיצד הוא יודע מה לעשות?
פרויקטים של מייבן מוגדרים בדלתאות (deltas): ההגדרה הבסיסית נמצאת ב super pom.xml – קובץ שנמצא בתוך אחד ה jars של מייבן עצמו (ואפשר, אך לא כדאי, לשנות אותו). הגדרות נוספות מגיעות מה settings של מייבן או מחושבות בזמן ריצה (כמו \"תיקיה נוכחית\"), אח\"כ מ pom.xml אבות של ה pom.xml המדובר (בפרויקט גדול – מרכיבים קבצי pom.xml בהיררכיה), ואז לבסוף, מה pom.xml הנוכחי – שבמקרה שלנו הוא כמעט ריק.
במקרה שלנו אין pom.xml אב, והקובץ שלנו כמעט ריק – אז ההתנהגות בה אנו חוזים מגיע בעיקר מה super pom.xml ומה settings. הרכבה של כל השכבות המוגדרות בקובצי ה pom.xml הרלוונטיים השונים נקראת effective pom.xml, ניתן לראות  אותה ב eclipse בתוך ה IDE. ב Intellij אני לא מכיר דרך לראות אותה, ולכן אני מריץ את ה command line הבא:

mvn help:effective-pom -Doutput=effective-pom.xml

דוגמה ל Effective-pom.xml מינימליסטי

הנה ה effective-pom.xml שנוצר לנו. בואו נבחן אותו. שימו לב שכמה חלקים הם collapsed:

  1. ה dependencies היחידים הם אלו שהגיעו מה pom.xml שלנו – תלות ב Junit 3.8.1
  2. ה repositories וה pluginRepositories כרגע הם ה central repository של מייבן, קרי http://repo.maven.apache.org/maven2.
    ה repositories מכילים הרבה (מאוד) פרויקטי open source ו/או maven plugins – אותם מייבן ידע להוריד אלינו למחשב ע\"פ הצורך. כאשר עובדים ב IDE וזקוקים לאיזו ספרייה – פשוט מוסיפים אותה כתלות ב pom.xml ומייבן יביא אותה לבד ב build הבא. אם הספרייה שציינתם תלויה בספריות אחרות – מייבן תביא גם אותן. כמו כן – אותה הורדה תתרחש גם אצל מפתחים אחרים בצוות. זה היופי של ניהול התלויות של מייבן.
  3. כאן ניתן לראות את מבנה הספריות של הפרויקט, כפי שתיארנו אותו קודם (כ full paths). מייבן משתמש ב super pom.xml במשתני-סביבה בכדי להגדיר את הנתיבים, וה effective-pom.xml כבר מכניס בהם את הערכים.
  4. כפי שציינו, plugins הם אלו שעושים את כל עבודת ה build בפועל. ניתן לראות בדוגמה למעלה שני core plugins שמתארים את ההתנהגות של שלבי ה clean וה install של מייבן.
    Plugins אחרים שלא נכנסו לצילום המסך הם:
    1. maven-resources-plugin
    2. maven-surefire-plugin – הפלאג-אין של מייבן להרצת בדיקות-יחידה. אין לי מושג למה הוא קיבל \"שם מגניב\", ורבים אחרים – לא.
    3. maven-compiler-plugin
    4. maven-jar-plugin – כפי שהשם מצביע, הוא פשוט אורז קובץ jar.
    5. maven-deploy-plugin
    6. maven-site-plugin – הפלאג-אין של מייבן ליצירת תיעוד לפרויקט

בהמשך, נרחיב עוד על Plugins והקונפיגורציה שלהם.

Build Lifecycles

המודל של מייבן מגדיר 3 פעולות שמייבן יודע לעשות:
  • לבנות תוכנה (ואולי גם להתקין אותה) – מה שנקרא ה default lifecycle
  • לנקות שיירים (קבצים זמניים וכו\') מבנייה קודמת (בעקרון: ספריית ה target) – מה שנקרא clean lifecycle
  • בניית תיעוד לתוכנה (יצירת מערכת דפי html) – מה שנקרא site lifecycle, כלומר אתר אינטרנט (סטטי) הכולל את התיעוד של התוכנה.
כל אחד ממחזורים אלו בנוי מרשימה מוגדרת-מראש של שלבים (phases).
המשתמש יכול לבחור לבצע רק חלק מהמחזור שהוגדר ע\"י מייבן. למשל: להפעיל את ה default lifecycle רק עד שלב הקומפילציה. שלבים מוקדמים יותר במחזור, כגון validation של פרויקט המייבן או יצירת ה resources הנדרשים – יופעלו, אבל השלבים המאוחרים יותר (כמו בדיקות או התקנה) – לא יופעלו.

שלבי ה Lifecycle השונים של מייבן, כאשר השלבים החשובים / היותר שימושיים – מוגדשים

כאשר אנו מפעילים את מייבן בכדי לנקות שיירים של בנייה קודמת, אנו מקלידים ב command line:

mvn clean

מה שיגרום למייבן לזהות שזהו שלב (phase) של ה clean lifecycle ולהפעיל את ה livecycle הזה עד שלב ה clean. שלב ה pre-clean יתבצע, אך שלב ה post-clean – לא יתבצע. כמובן ששלבים רבים במחזורי הפעילות של מייבן הם שלבים ריקים – אלא אם נגדיר בהם משהו.

בכדי להפעיל את כל ה clean lifecycle יש להקליד mvn post-clean. בד\"כ אנו מסתפקים ב clean, הקצר יותר להקלדה.

האם איי פעם תהיתם מדוע אתם מקלידים (הפקודה הכי נפוצה אולי) \"mvn clean install\",
אבל לא \"maven clean compile install\", או משהו דומה?

התשובה עכשיו ברורה: clean נדרש מכיוון שהוא שלב ב lifecycle שונה מה default lifecycle. כאשר מפעילים את mvn install – הוא יבצע את כל 20 ומשהו השלבים מ validate ועוד install. הוא רק לא יעשה deploy.

הנה כמה מלים על מה שמייבן עושה בשלבים השונים של ה default lifecycle:

  • validate – מוודא שפרויקט המייבן תקין, למשל: ולידציה של ה pom.xml, שכל המשתנים שבשימוש – מוגדרים, וכו\'.
  • generate sources / resources – שלבים שהוגדרו בכדי לשמש לשלבי pre-proccesing להתרחש (במידה ואתם משתמשים בכלים שמג\'נרטים קוד או resources).
  • compile – קומפילציה של קוד תחת ספריית main (לא כולל קוד של בדיקות)
  • process-classes – שלבי post processing על קבצי ה class. שקומפלו, למשל \"אריגה\" של AspectJ על קבצים שכבר קומפלו (יש אפשרות כזו).
  • test-compile – מקמפל רק את קבצי הבדיקות. אם אתם לא מתכוונים להריץ בדיקות – חבל על הזמן לקמפל את קוד הבדיקות, לא?
  • package – אריזת הקוד ל jar, war, ear וכו\'.
  • integration-tests – שלב מיוחד של הרצת בדיקות על מערכת \"חיה\". מתקין את ה deployable שכרגע נארז על מערכת בדיקות, ומריץ מולה בדיקות אינטגרציה / מערכת (איך שאתם קוראים להן). ה plugin של מייבן שמריץ בדיקות אינטגרציה נקרא \"failsafe\".
  • verify – שלב בו ניתן לבצע בדיקות נוספות על ה package הארוז – לוודא שהוא תקין.
  • install – השם של השלב הזה הוא מעט מבלבל: ההתקנה היא של ה deployable ל local maven repository – ולא לשרת ה production כמו שאולי זה נשמע. ה local repository הוא צד של מייבן שעדיין לא נגענו בו בפוסט זה. נאמר כרגע שזו איזה תיקייה של מייבן בה הוא שומר deployables, pugins ו ספריות שנדרשות בגלל התלויות.
  • deploy – עושה את מה שאפשר לחשוב: מתקין את ה deployable על שרתי ה production.

סיכום

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

  • מהם בדיוק ה repositories?
  • כיצד ה plugins משתמשים בשלבים השונים שמייבן מגדיר? מהם ה goals?
  • ואולי הכי פרקטי: כיצד משנים את הגדרות ה pom.xml ורותמים את מייבן לצרכים הייחודיים של הפרויקט שלנו ?
אני מקווה לכסות לפחות כמה מנושאים אלו בפוסט המשך.

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

[א] Groovy היא (מלבד ה nested classes) בעצם superset של ג\'אווה. לכאורה, מאוד קל למתכת ג\'אווה לעבור אליה: לשנות את סיומות הקבצים ל groovy. ולהימנע משימוש ב nested classes. בפועל, כמעט כל דוגמאות הקוד של gradle משתמשים בתחביר מתקדם של שפת Groovy – שיהיה זר ומוזר למתכנת ג\'אווה שלא ישקיע זמן ללמוד אותו ואת הדקויות שלו.

[ב] בגלל שמייבן מתייחס ל qualifier כטקסט, יש פה pitfall מסוים:
גירסה:

0.9.9-CR10 

תחשב כמוקדמת יותר מגירסה:

0.9.9-CR2

(בגלל שהתו \"1\" נמוך בערך ה ASCII שלו מ \"2\").

לא טוב היותה לבדה: על אינטגרציה של מערכות (מבוא)

ישנו שלב בחיי בניית תוכנה בו מגיע הדרישה לפיצ'ר שברור שלא סביר לבנות אותו לבד.
זה לא בגלל שבוני המערכת לא יודעים לכתוב כזה פיצ׳ר. הרבה פעמים זה גם לא עניין של מאמץ או זמן פיתוח – אלא עניינים הקשורים למשתמשים או למערכת האחרת:
  • זה יכול להיות Waze – שאין סיכוי סביר לרוב החברות להקים מאגר / קהילה מקבילה.
  • זה יכול להיות פייסבוק – שרשימת החברים שלי כבר מתוחזקת שם היטב.
  • זה יכול להיות גוגל דרייב – שסתם אני רגיל ואוהב להשתמש בו.

אפילו אם תספקו למשתמש אותן סט יכולות באיכות מעולה – זה לא ישתווה לשירות אליו המשתמש רגיל.

נהוג לומר:

!If you can't beat them – join them

ואם אתם לא יכולים להחליף מערכת אחרת – כדאי שתתחברו אליה.

צורות התחברות למערכת אחרת

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

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

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

אינטגרציה של הפעלה (Invocation)

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

אפליקציית Rest שלה כפתור שמזניק את Waze. שימושי.

ברוב הפעמים מערכת ההפעלה / סביבת ריצה מספקת את התשתית לאינטגרציה ומי שמעוניין באינטגרציה צריך:

  • ללמוד את הפורמט/פרוטוקול להעברת context (למשל: כתובת לניווט) לאפליקציית היעד.
  • (צעד רשות): לוודא שאכן האפליקציה השנייה זמינה (כי ניסיון להפעיל אותה מבלי שהיא זמינה – עלול להראות לא טוב).

דפוס חוזר של הפעלה של אפליקציה כזו הוא decoupling by intent:

  • אני מבקש מאפליקציית ניווט כלשהי (ולא דווקא Waze) לענות לקריאתי – ושולח את הכתובת לסביבת הריצה שתמצא לי אפליקציה שיכולה לענות על כזו בקשה.
  • סביבת הריצה מפעילה אלגוריתם החלטה (בד"כ: רשימת העדפות פשוטה) ומקשרת את ההודעה שלי לאפליקציה המתאימה ביותר (כלומר: הראשונה ברשימה).
דוגמה אחת ל decoupling by intent יכולה להיות מערכת ההפעלה "חלונות", בה ניתן "לקשור" אפליקציה (למשל Word) לסיומת של קובץ (למשל docx.*) ואז הפעלה של הקובץ (פקודת start ב command line) תפתח את הקובץ באפליקציה הקשורה. אני יכול גם להתקין Libre Office ואז קבצי ה docx.* יפתחו בעזרת אפליקציה בשם Writer.
דוגמה אחרת היא מערכת ה intents של מערכת ההפעלה אנדרואיד בה ניתן לקשר אפליקציה לסוג מידע (כתובת, URL וובי, מספר טלפון, תמונה וכו'). "אלגוריתם ההחלטה" עשוי לערב את משתמש הקצה, להציג לו את האפליקציות שיודעות לטפל בסוג זה של מידע – ולתת לו לבחור.
אספר שבמערכות שאנו עובדים איתן ב SAP יש יכולת לנהל סט חוקים מורכב המשפיעים על אלגוריתם ההחלטה – אולם רק לקוחות מעטים באמת משתמשים ביכולות המתקדמות האלה. המערכת המורכבת היא לא רק משוכללת, אלא גם קשה להבנה ולשימוש. רוב הלקוחות משתמשים בחוקים פשוטים הדומים לאלו של מערכת ההפעלה "חלונות" (מין רשימה עם priorities, ע"פ האפליקציה הראשונה שזמינה).
פריט המידע שמועבר בין המערכת המקומית לאפליקציה המרוחקת עשוי, בתסריטים של Enterprise, להיות זיהוי של אובייקט עסקי – שאותו האפליקציה המרוחקת תוכל לערוך / לבצע עליו פעולות (על בסיס גישה משותפת של האפליקציות לבסיס הנתונים, או סוג של RESTful APIs).

מנגנון  של decoupling המתבסס על כוונה (intent) מאפשר:

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

אינטגרציה של נתונים (data integration) – מושגים בסיסיים

נוהגים לחלק אינטגרציה של נתונים ל 4 סגנונות עיקריים [א]:

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

  • שכפול נתונים בין מערכות (Replication) או סנכרון נתונים בין מערכות. סנכרון זה מצב יותר בריא, בד"כ 🙂
  • קיבוץ (Aggregation) נתונים ממקורות שונים למקום אחד – עבור דו"ח או Dashboard (לוח בקרה).
  • הרכבה של תהליכים "עסקיים", הרכבת כמה אפליקציות פשוטות לאפליקציה מרוכבת ומועילה יותר (Business Processes). אני מדבר ב"שפה עסקית" אך זהו גם הסיפור של אפליקציית Rest שפותחת את WAZE שפותחת את גוגל (לקבל עוד נתונים בעקבות פרסומת בדרך).
  • סיפוק שירותים נקודתיים, כדי למנוע שכפול נתונים או פונקציונליות – למשל שירות של מילון (Dictionary) או שירות קבלת כתובת דואר של עובד. שירותים אלו יכולים לשמש UI (כלומר: משתמש קצה) או מערכות אוטומטיות.

כן, אבל…

אם נדמה לנו שמאמץ האינטגרציה נגמר בהעברת נתונים או הזנקה של אפליקציה – אנו מעט אופטימיים.
אינטגרציות כוללות גם לא מעט קשיים בדרך:
  • אפשור גישה ברמת הרשת.
  • עבודה בפורמטים שונים.
  • אינטגרציה עם מערכות Legacy.
  • אימות זהות ואבטחה.
  • אנשים אחרים / עולם מושגים שונה / DNA ארגוני שונה.
  • מערכות Legacy / שאינן יכולות להשתנות.
  • הבדלי מהירות / קיבולת בין המערכות – שלא לדבר על זמינות.
  • סינכרון ו Concurrency.
ואחרי שכל האינטגרציה "הסתיימה":
  • שינויים ב API / חוזה (contract) של המערכת המרוחקת.
הבהרה: לא כל אינטגרציה באמת מחייבת פתרון / התעסקות עם כל הנושאים הנ"ל, אך זו הרשימה של האתגרים השכיחים.אינטגרציה היא לא דבר חדש ויש Framework / מערכות לאינטגרציה, כדוגמת TIBCO (חבילת מוצרים גדולה), BizTalk של מייקרוסופט או Apache Camel (הקטן והחביב). למה לא פשוט להשתמש בהן – ולא "לשבור את הראש"?
ספריות / מערכות אלו הן כלי עזר לאינטגרציה – אך לא "פתרונות קסם" ש"מסירים מהדרך" את הבעיות הנ"ל. למשל: במקום לכתוב 100 שורות קוד בכדי להאזין לשינויים בתיקיית קבצים, לפרסר את הקובץ ולשלוח את המידע החדש שנוסף כ JMS message – תוכלו אולי לכתוב בעזרת הספריה 4-5 שורות דקלרטיביות או ב DSL שיעשו אותה עבודה. בכל זאת, לא תמצאו שם פתרונות אוטומטיים לבעיות אבטחה, הבדלי מהירות או זמינות בין המערכות וכו'. בטח שלא לבעיות של תקשורת בין בני-אדם 🙂
יהיה עליכם להבין את האתגרים האפשריים, לחשוב, לנתח – ולפתור.

אפרופו יש קטגוריה של פתרונות בשם ESB (קיצור של Enterprise Service Bus) – שמופיעים כמודול ברוב פתרונות ה Middleware של החברות הגדולות (IBM, Oracle, TIBCO וכו') או בגרסאות חופשיות (למשל Apache Mule).
אלו בד"כ פתרונות יותר כבדים מ"מערכות האינטגרציה" אותן הזכרתי, הם קשורים בצורה הדוקה בד"כ לארכיטקטורת SOA שמרנית, ונחשבים כלא כ"כ מוצלחים (כקונספט – אני לא מדבר על המימוש).
אני לא מנסה לדבר עליהם, ולא רוצה שתבינו בטעות שכדי לבצע אינטגרציה – זקוקים לתשתית כלשהי. כלים שכאלו כדאי להכניס לשימוש כדי לחסוך זמן (במיוחד כשיש הרבה עבודה) – לא כדי "לפתור את הבעיה".

לא קל…

תהליך אינטגרציה: ממה להיזהר? וכיצד?

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

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

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

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

עבודה בפורמטים שונים
בעוד מערכת אחת עוטפת את המידע ב XML בצורה אחת – והשנייה ב XML בצורה אחרת. עצם השימוש "המשותף" ב XML לא מוסיף לאינטגרציה כמעט דבר, אם הפורמטים שונים. גם בתוך ה XML (או JSON, CSV וכו'):מערכת אחת מתארת תאריך בפורמט ארוך – והשנייה בפורמט קצר, אחת כתובת בשדה אחד והשנייה במספר שדות שונים, וכו'.
עבור קריאות מרוחקות (RPC), ההבדלים יכולים להיות גדולים יותר: DCOM מול CORBA או RMI מול REST API – צורת התקשורת שונה, ולא רק פורמט אותו ניתן להמיר.

יש גם נושא של Data Integrity: מערכת אחת מוכנה לקבל רשומה כאשר שדה x חסר (ערך ריק) – ומערכת שניה לא מוכנה לקבל זאת. אולי תאימות בין הנתונים: מערכת אחת בודקת את ערכי השדות שיתאימו לכלל מסוים – והשנייה לא.

את המידע ממירים בעזרת Adapters (או Transformers/Normalizars במערכת מורכבת יותר) – בכדי לתאם בין הפורמטים / פרוטוקולים. לפעמים עושים תהליך נוסף של Data Quality – תיקון הנתונים בכדי לעמוד ב"סטנדרטים" של אחד הצדדים (שלמות, דיוק וכו').

עניין של פורמטים הוא בד"כ לא "נושא מורכב" (זו קרקע מצוינת לכיסוי עם Unit Tests) – אך זו עבודה. בד"כ ככל שהמידע הוא Human Friendly – ההמרה תהיה קלה יותר. המרה של מידע בינארי, נוטה להיות מורכבת יותר.

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

כאשר אנו רוצים לשלוף נתונים ממערכת Legacy שלא התאימה את עצמה ל export של המידע לו אנו זקוקים – משימת האינטגרציה יכולה להיות קשה. תת-תחום, מוכר יחסית, של נושא זה הוא העולם של Web Scrapping– שליפת נתונים ממערכות ע"י פענוח ה HTML שהן מייצרות (ולא תמיד בהסכמתן). משימות של Scraping בדרך כלל יותר נוח לעשות בשפות דינאמיות עשירות בספריות לטיפול בטקסט כמו פייטון או רובי, אם כי יש מגוון רחב של ספריות. אפשרויות אחרות הן "דיג" של נתונים מתוך לוגים או קבצי נתונים שהמערכת מספקת – אך תוכננו לצורך אחר.

אימות זהות ואבטחה
בעולם הווב / Social יש היום את OAuth שמקל על המשימה – לשלוף נתונים בצורה מאובטחת ממערכת מרוחקת. בעולם ה Enterprise התמיכה ב OAuth היא עדיין מועטה.
כאשר משתמש מזניק (invocation) אפליקציה אחרת – נרצה לחסוך ממנו הקשה נוספת של משתמש/ססמה, בעזרת SSO. כנ"ל לגבי שליפת / עדכון נתונים. בהרכבה של תסריטים עסקיים מורכבים, ייתכן והמשתמש יפעיל כמה אפליקציות שונות בכמה דקות. הקלה של ססמה כל פעם – היא שוחקת ומכבידה.

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

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

הבדלי מהירות / קיבולת בין המערכות

נושא זה הוא מעט טריקי, ולעתים מפספסים אותו עד שלב מאוחר. כאשר אנו צורכים שירות/מידע ממערכת אחר יש להתייחס למצב בו המערכת לא זמינה. האם הקוד שלנו ידע להתמודד זה במצב סבירה או שעוד ועוד threads ילכדו ב timeout על קריאה למערכת המרוחקת?
להבהיר: כאשר כל ה threads שלנו תקועים – לא נותרים threads ב Pool לפעולות אחרות, ואז ייתכן שגם המערכת שלנו – נתקעת ולא מגיבה.כלומר: אי-זמינות של מערכות הוא מדבק, ויש לבנות מנגנונים (נקראים Circuit Breakers) למניעת הידבקות זו.
Circuit Breakers יכולים להופיע כמנגנונים האוכפים timeout קצר בניסיון לקריאה ממערכת מרוחקת.
יש כאלו שיזהו רצף של תקלות וימנעו ניסיונות תקשורת – עד אשר תהיה התערבות ידנית / מנגנון שמזהה התאוששות יפעל.

Circuit Breaker מתוך הפוסט של מרטין פאוולר בנושא.

וריאציה אחרת היא בהבדלים במהירות או Scalability בין המערכות:

נניח שהמערכת המקומית מסוגלת לטפל באלפי בקשות בשנייה (tps) אך המערכת המרוחקת – לא ביותר מ 50 קריאות בשנייה. ברוב המקרים זה מספיק – כי רק במקרים מאוד מסוימים אנו פונים למערכת המרוחקת. מצד שני, פעם בכמה זמן יכול להיות peak בו אנו פונים למערכת המרוחקת 100 פעמים בשנייה – גורמים לה לקרוס, ואז אם אין לנו מנגנון הגנה, אנו יכולים לקרוס בהמשך בעצמנו. הכל בגלל אינטגרציה קטנה ושולית.מנגנון הגנה אפשרי הוא ליצור (מטאפורה:) סוג של צינור מצר, בעצם זה סוג של counting lock שלא מאפשר למערכת שלנו לבצע יותר מ x קריאות למערכת המרוחקת בו-זמנית. אנו מגנים עליה – כי זה אינטרס שלנו שהיא לא תקרוס. מנגנון כזה נקרא (Throttling (controller. כמובן שהמערכת המרוחקת יכולה לקרוס מסיבות אחרות – וזה לא תחליף ל Circuit Breaker בסיסי יותר.

שינויים ב API / חוזה (contract) של המערכת המרוחקת

ה APIS במערכת המרוחקת עלולים להשתנות עם הזמן.
אפילו יותר מכך: לפעמים ה API (החלק המוצהר) נשאר כפי שהוא, אבל חלק אחר, לא מוצהר, ב contract משתנה: סדר פעולות, Exceptions שנזרקים או תופעות לוואי אחרות. כל אלו – יכולים לשבור את האינטגרציה ודורשים תחזוקה.
ישנם מקרים בהם השינויים הם תדירים מאוד (בעיקר מוצרים צעירים) – ואז התחזוקה היא מעמסה רצינית.
עוד מצב שמתרחש בתדירות מסוימת הוא החלפת מערכות: מעבר ממערכת A למערכת B – ואז כל האינטגרציה מתחילה מחדש. זה נשמע כמו "מקרה לא-שגרתי", אך הכל עניין של סדרי גודל. ללקוחות של SAP יש מאות, ולפעמים אלפי אפליקציות בארגון והרבה אינטגרציות – כך שהחלפה של כמה מערכות כל רבעון היא דבר דיי שגרתי.
בקיצור: אינטגרציות הן יקרות למימוש. לפעמים טיפה יקרות, ולעתים מאוד יקרות. לו היו זולות יותר – כנראה שהיינו רואים עוד מהן, כי פעמים רבות יש להן ערך משמעותי למשתמש.

סגנונות אינטגרציה וכיצד הם מתמודדים עם האתגרים השונים

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

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

יתרונות:

  • קל למימוש
  • יעיל מבחינת ביצועים (גישה ל raw data)
  • Consistency (יחסי) של הנתונים
חסרונות:
  • אין הכמסה. מערכת אחת נוגעת במבנה נתונים של מערכת אחרת. ניתן לראות זאת כממשק מאוד מאוד רחב בין המערכות – וזו הסיבה העיקרית שגישה זו היא הכי-פחות מועדפת עלי באופן אישי, מכל הסגנונות. שינויי סכמה משפיעים מיידית על 2 המערכות.
  • גישה ישירה לבסיס הנתונים עוקפת Business Logic ואימות נתונים שבא איתה, Caches של ORM או שכבות עליונות וכו'.
  • בסיסי נתונים (רלציוניים בעיקר) הם מאותגרים scalability והוספת מערכת נוספת שעובדת על אותו בסיס נתונים יכולה להיות מגבילה / לדרוש שדרוג יקר של החומרה.



אינטגרציה ע"י קריאה מרוחקת (RPC)
RPC הוא קיצור של Remote Procedure Call (שם שמקורו היסטורי) והכוונה היא לכל הטכנולוגיות של הפעלת פונקציות מרחוק: REST, RMI, XML-RPC, אולי RPC ברמת מערכת ההפעלה ועוד.

יתרונות:

  • הכמסה בין המערכות
  • ממשק מוגדר היטב
  • online
חסרונות:
  • תלות חזקה בין המערכות (ממשק + ידע על מיקום/כתובת המערכת המרוחקת)
  • תקשורת סינכרונית בלבד

אינטגרציה ע"י שליחת הודעת (messaging / events-based).
שליחת הודעות נעשית בד"כ דרך מנגנון לשליחת הודעות ייעודי, מה שנקרא MOM (קיצור של Message Oriented Middleware). מערכות נפוצות שבשימוש הן Apache ActiveMQ, RabbitMQ, רדיס (Redis) ומנגנון ה Pub-Sub שלו (עליו כתבתי בפוסט בעבר), Apache Kafka (ל Scale גבוה) או מימושים שונים של מנועי JEE/חברות התוכנה הגדולות.

יתרונות:

  • גמישות רבה לאינטגרציות מורכבות
  • פוטנציאל Scalability נהדר (בכמות הנתונים)
  • אפשרות לאסינכרוניות ו reliable messaging (אולי תכונות חשובות, לא דווקא יתרונות)
חסרונות:
  • תוואי רשת יכול להקשות על scalability במספר המערכות המעורבות באינטגרציה
  • איתור תקלות יכול להיות מורכב ודורש לוגים / כלי Monitoring
  • פרגמנטציה רבה של תשתיות זמינות

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

יש גם מרחב גדול של מימושים באמצע מבוסס REST/HTTP/JS – שזה סוג של RPC, אבל עם טכנולוגיות ווב מודרניות ופשוטות (וקצת פחות "RPC by the book")

סיכום

שוב תכננתי פוסט קצר….
נושא האינטגרציה הוא צומת מפגש של מספר נושאים: רשתות ותקשורת, Data, "מערכות גדולות" – אך יש גם כמה תחומי ידע ש"ייחודיים" לאינטגרציה. יש הרבה ידע שקשור בתחום זה.
בפוסט זה סקרתי, בצורה רוחבית, כמה עקרונות בסיס של נושא האינטגרציה ואתגרים איתם יש להתמודד.
נושא האינטגרציה בין מערכות תפס תאוצה מחודשת בענן. מה השתנה מעולם ה On-Premise?
יש נגישות קלה יותר ברשת והרשאות. אך שאר האתגרים נותרו פחות או יותר כפי שהיו.
אולי הדרישה לניהול מרחוק והדרישה ל"אלסטיות" של המערכות מעודדת יותר ארכיטקטורה מונחית שירותים / Micro-services? – מה שהופך את האינטגרציה לקלה יותר. לא יודע.
שיהיה בהצלחה!
—-
[א] המקור המוקדם ביותר שמזכיר חלוקה זו, שאני מכיר, הוא הספר Enterprise Integration Patterns, אולם נתקלתי בחלוקה זו שוב ושוב ממקורות שונים.

דפוסי עיצוב (Design Patterns): ימים יפים, ימים קשים

[הפוסט נכתב בשיתוף עם רחלי אבנר, Area Architect בחברת SAP]

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

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

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

כיצד ומדוע עלו ה Patterns לגדולה?
מדוע אם כן יש עליהן ביקורת, והאם יש לכך הצדקה?

על כך בפוסט שלפניכם.

כריסטופר אלכסנדר

שורשים

את הרעיון של Design Patterns (להלן: דפוסי עיצוב) התחיל ארכיטקט בשם כריסטופר אלכסנדר אי שם בשנות השבעים.
כריסטופר אלכסנדר לא היה ארכיטקט תוכנה, כי אם ארכיטקט בנין ("אדריכל"). וגם דפוסי העיצוב שהגדיר – היו דפוסי עיצוב של אדריכלות. כריסטופר אלכסנדר לא היה אדריכל שגרתי: השכלתו לפני ארכיטקטורה כללה פיסיקה, כימיה ומתמטיקה (יש לו תואר שני במתמטיקה), ובנוסף לעיסוקו באדריכלות הוא היה גם contractor ("קבלן") – מה שנותן לנו להבין שמצד אחד ראשו בעולמות התאורטיים אבל מצד שני רגליו נטועות עמוק בעולם המעשה.

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

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

מ-ש-ע-מ-ם

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

עדיין, זה לא מבנה שגורם לנו להרגיש "בבית".

הנה מבנה מוצלח יותר:

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

את שרשרת ההבחנות סיכם בשלושה ספרים, שהמשמעותי ביניהם נקרא: A Pattern Language: Town, Building, Construction.

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

ספרי דפוסי העיצוב של כריסטופר אלכסנדר

דפוסי-עיצוב בתוכנה

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

את הרעש הגדול עשו ארבעה: אריך גאמה[ב] ניהל שיחה עם ריצארד הלם בה עלו הרעיונות לספר. אח"כ הם צרפו את ראלף ג'ונסון וג'ון וילידס. ארבעתם ידועים כ "Gang Of Four" (או בקיצור GOF). רובם חוקרים / בעלי רקע משמעותי של מחקר במדעי המחשב – אבל הם כתבו את הספר, כנראה הנמכר ביותר בתחום, אחד המשפיעים ביותר ושנחשב למאוד מעשי ושהקדים את "האקדמיה" בשנים.

"הספר"

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

Facade, Proxy, Adapter, Singleton ועוד – הם מושגים שהטביע בעולם התוכנה ספר זה.
"דפוסי העיצוב" היו כבר קיימים בעולם: לכל דפוס עיצוב הם סיפקו מספר דוגמאות של יישומים במערכות קיימות. בספר הם אספו אותם, תיעדו אותם ויצרו שפה חדשה להנדסת תוכנה Object Oriented.

ההצלחה של הספר הייתה חסרת תקדים, וזעזעה (לטובה) את עולם התוכנה. בעקבותיה קמה "תנועה" של Patterns ונכתבו, בזמן קצר יחסית, מספר רב של ספרים עם Patterns רבים נוספים (ביניהם סדרות כגון PLOP או POSA). ה GOF החלו אף לדבר על הוצאת מהדורה שנייה.

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

גם היום, 20 שנה אחרי, ספרים חדשים משתמשים במותג "Patterns" בכדי לקסום לנו, ולהימכר טוב יותר:

סדקים ראשונים

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

הזמן גם עבר… והאופנות קצת השתנו – ויצרו סדקים נוספים:

  • תנועת האג'ייל: את התכנונים (Design) ה Top Down, החליפו ב Evolutionary Design ו Bottom Up. היכן ש Design Patterns כבר פחות מתאימים.
  • בזמן הוצאת ספר דפוסי-העיצוב, תכנות OO (או תכנות מונחה היבטים – AOP) היה "הדבר הגדול הבא". היום תכנות OO הוא נפוץ מאוד – אבל "הדבר הגדול הבא" הוא משהו בין תכנות דינאמי לפונקציונלי – קצת שונה מהעקרונות של OO. לשפות אלו, דפוסי העיצוב המוכרים – פחות מתאימות.
  • "אמיתות של הנדסת תוכנה" גם הן השתנו. אם פעם שימוש חוזר בקוד היה העיסוק המרכזי, היום אלו יותר פשטות של הקוד ו time-to-market. העיקרון הפתוח-סגור (Open-Closed Principle) פעם היה מאוד פופולרי (ורואים את חותמו בספר של GOF) – אך כיום הוא שנוי במחלוקת. דפוסי העיצוב מהספר של GOF מקדמים הרבה שימוש חוזר והפשטה – וקצת פחות פשטות.

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

דפוסי העיצוב באו להלחם בעולם עם Under-Engineering, אך יצרו עולם של Over-Engineering.

לזרוק ולשרוף?!

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

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

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

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

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

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

לו רק הייתה יותר הכוונה…

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

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

כיצד להשתמש בדפוסי עיצוב בצורה נבונה?

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

צדדים טובים:

  • פתרונות מוכנים ומעולים לבעיות תכנון. נכון חלקית: אלו פתרונות טובים לבעיות מאוד מסוימות, וקיים סיכון סביר (ומוכח) – שאלו לא הפתרונות הכי טובים למערכת שלכם. זכרו: גם בספר "Design Patterns" – לא תמיד באמת מדברים עליכם.
  • שפה משותפת: ברגע שגם אני וגם בין-שיחי מכירים את דפוסי העיצוב (למשל) "Strategy" – יהיה לנו הרבה יותר קל לתקשר על בעיה / פתרון טכני מסוים. מילה אחת יכולה להחליף הסבר של כמה דקות. חשוב ללמוד דפוסי-עיצוב בכדי לקבל מושגים משותף ולהפוך את התקשורת בזמן העבודה ליעילה ומדויקת יותר. כמו כן, היחסים המוכרים בין תבניות שונות מאפשרות בסיס לשיחה על מבנים מורכבים יותר (למשל: MVC). שפה משותפת היא התועלות המוסכמות ביותר בימנו המיוחסות לדפוסי-עיצוב.
  • מקור השראה: לא חייבים ליישם את דפוס העיצוב כלשונו. ניתן לעשות וריאציה, ניתן לקחת רק רעיון אחד מדפוס העיצוב – ולעשות משהו אחר לגמרי. לגישה זו יש הרבה פוטנציאל, ולשם כך טוב (באופן כללי בכלל) להכיר תכנונים לא-טריוואילים של מערכות אחרות.
צדדים פחות טובים:
  • הנדסת-יתר (over-engineering) – עסקנו בבעיה זו די והותר.
  • פוטנציאל לקיבעון: מצב בו למישהו קשה ליישם מבנה דומה-חלקית לדפוס העיצוב, כי הוא מרגיש ש"דפוס העיצוב" חכם בוודאי ממנו – ואז הוא נגרר ליישום פחות מוצלח (אם כי שמתועד בספר אגדי).
  • פוטנציאל לקיבעון כרוני: אנשים שלא מוכנים להאמין שיש פתרון טוב יותר (בהקשר המסוים) מזה המתואר בספר האגדי של "Design Patterns". לכו תשכנעו אותם.

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

הדרכים המומלצת היום להשתמש בדפוסי עיצוב הן:

  • ככלל: אל תתחילו לכתוב קוד ולהשתמש בדפוסי-עיצוב. אל תעשו הכנה ל Adapters – כאשר יש רק יישום אחד מוכר. "בטח בעתיד יהיו עוד – בואו נכין את הקרקע מעכשיו" – זו לא גישה אג'ילית.
  • Refactoring to Patterns – במידה והגעתם לקוד שיש בו ריחות (code smells) המצביעים על בעיה בקוד (שכפול קוד ברור, תלויות לא רצויות וכו')….
  • שקלו את דפוס העיצוב המתאים. זכרו שדפוסי עיצוב מגבילים לפעמים את גמישות הקוד בכיוון מסוים. לא על כל 5 שורות קוד כפולות – כדאי להשתמש ב State, למשל.
  • עשו Refactoring ושנו את הקוד כך שיישם את דפוס העיצוב שהחלטתם שהוא מוצדק – או גרסה דומה שלו. חשוב להבין "מה הקטע" של כל דפוס עיצוב – ולא סתם ליישם אותו "ע"פ הספר".
הספר הזה הוא כבר בן עשור. לו היה נכתב כיום – אני מניח שהמסרים שלו היו נראים קצת אחרת (יותר החלטיים).
עדיין – זה ספר שיכול לעזור

אפרופו: בהינתן ההבחנה ש"שפה משותפת" היא ערך עיקרי של דפוסי עיצוב ו"שימוש מופרז" היא הסכנה המרכזית – ניתן להצביע על Anti-Patterns ככלי שיכול להיות מצוין: Anti-Patterns הם תיאורים של דפוסים שליליים ולא-מומלצים מהם יש להימנע או לפחות להיזהר. אפשר לציין Anti-Patterns כגון "Gold Plating" (השקעה מופרזת באלמנט לא-חשוב), "Project Chicken" (אף אחד בפרויקט לא יכול לעמוד במשימה / לוחות הזמנים – אך כולם פוחדים להיות האדם הראשון שמודה בזה. לאחר שאחד הודה – כל השאר מצטרפים "אם הוא לא יעמוד ביעד – זה יתקע גם אותי"), "Death March" (עבודה על פרויקט ללא סיכוי הצלחה – אך מישהו "למעלה" מסרב להכיר במציאות הזו והפרויקט ממשיך) ועוד.

היופי ב Anti-Patterns הוא שאף אחד לא "ירוץ" ליישם אותם – זה לא מקור לגאווה. אין over-engineering.
החיסרון: שום מקור לא הצליח לייצר מומנטום מספיק גדול בכדי להפוך שפה כלשהי של Anti-Patterns לנפוצה מספיק בכדי שתהיה ידועה ומוסכמת בקרב קהל משמעותי [ד].

דפוסים כתהליך של התחדשות

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

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

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

Proxy ו Observer אולי הפכו לחלק משפת JavaScript (בצורת bind ו object.observe, בהתאמה) אבל עם התפתחות השפה והאתגרים שלה נוצרו גם דפוסים המתאימים להתמודדות עם האתגרים החדשים (לדוגמה: Module).

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

סיכום

  • היללנו את דפוסי העיצוב.
  • השמצנו וביקרנו את דפוסי העיצוב.
  • לקראת הסוף: ניסינו לספק תמונה רחבה ומאוזנת.

כדאי ללמוד על דפוסי-עיצוב כשפה, תוך כדי שימוש בדוגמאות עדכניות ורלוונטיות. למשל:
במקום ללמד על Proxy על ידי ניתוח ה UML שהובא בספר של GOF ועיקרו היה מימוש פרוקסי ב ++C, אפשר להתעכב על הרעיונות שפרוקסי מייצג, ואז לראות אותם ממומשים בשפות השונות (proxy$ בספריית jQuery או bind בג'אווהסקרפיט. Dynamic Proxy בג'אווה וכו').

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

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

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

—-

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

דפוסי עיצוב של חווית משתמש (בעברית) וגם פרק בפודקאסט

—-

[א] איש מדעי המחשב שעסק רבות ב concurrency והספריה שכתב כהשלמה לג'אווה – נכנסה מאוחר יותר לסט הספריות הסטנדרטיות.

[ב] מאוחר יותר היה שותף לכתיבת הספרייה JUnit והוביל את התכנון של סביבת הפיתוח Eclipse.

[ג] "All problems in computer science can be solved by another level of indirection", שפעם נחשב לאמת מקובלת. רפרנס: http://www.dmst.aueb.gr/dds/pubs/inbook/beautiful_code/html/Spi07g.html

[ד] והיו כמה ניסיונות, למשל הספר AntiPatterns או הספר Adrenaline Junkies and Template Zombies.

[ה] על עבודתו של אלכסנדר בתחום הארכיטקטורה אפשר לספר הרבה. הנה שני מקורות מעניינים מאד בעברית:
פרוייקט תרגום שיתופי לעברית של הדפוסים של אלכסנדר, והבלוג של יודן רופא, שהיה תלמידו של אלכסנדר
מי שקורא את מה שנכתב על עבודתו מגלה תאוריה עמוקה הרבה יותר מ"רשימת מכולת של דפוסים" וכוללת אלמנטים פילוסופיים כמו גם שיטות מעשיות להוצאה לפועל של התאוריות האלה. אגב, שיתוף משתמשים ועבודה איטרטיבית – שמוכרים היום כחלק מעקרונות האג'יליים בהנדסת תוכנה, היו גם חלק מהותי בשיטת העבודה של אלכסנדר, וניתן לקרוא עליהם בשני ספריו האחרים The Oregon experiment ו-  A Timeless way of building.