-->

יום שני, 28 במאי 2012

מה הבעיה של Internet Explorer?

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

האמנם כך? אם כן - מדוע אתרים כגון Stat Owl עדיין טוענים שIE מחזיק את הכתר בבטחה?

ובכן, איסוף נתוני גלישה היא משימה לא פשוטה ולא מדויקת:
  • במשך השבוע האנשים גולשים בעיקר ממקומות העבודה, שם IE (אינטרנט אקספלורר) הוא הדומיננטי[א] ובסוף השבוע הם גולשים מהבית בעיקר בכרום או FF. ההבדלים במדידות בין יום ראשון (יום חופש) ויום שני (יום עבודה) הם דרמטיים.
  • זהות הדפדפן הנפוץ היא שונה למדי בין צפון אמריקה, אירופה, דרום אמריקה וסין.
  • האם מדובר על התקנות או על שימוש? למשל, על מכשירי טלפון יש הכי הרבה התקנות של דפדפן Opera (לרוב מכשירים זולים או ישנים - יש הרבה כאלה במדינות מתפתחות) . לא ברור בכלל איזה אחוז מבעלי הטלפונים האלה השתמש איי פעם בדפדפן שלו. אם מודדים את תעבורת הרשת - אז עיקר התעבורה נעשית מספארי (של אפל).
  • איך מודדים גלישה? זמן שהדפדפן פתוח? תעבורת רשת או מספר page views?
בהינתן שלכל אחד מהמקורות שמציגים נתונים על נתח השוק של הדפדפנים יש בסה"כ מדגם סטטיסטי, ובהינתן השאלות הנ"ל, ניתן להבין כיצד גופי מחקר שונים יכולים להגיע לתוצאות שונות כ"כ. נתח השוק של IE יכול לנוע בין 25% ל 55% - תלוי במקור.

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

הדפדפן הנפוץ - ע"פ מדינה. כחול = IE, ירוק = כרום, כתום = FF, אדום = Opera. מקור: wikipedia

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

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

קצת היסטוריה: מאיפה הגיע ה Quirks Mode וה Standards Mode?

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

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

אמנם ל Netscape היה יתרון שכבר היה לה מוצר קיים, אך תוך שנתיים מרגע השחרור של IE1 מייקרוסופט שחררה את IE4 שכבר נחשב למוצלח יותר מזה של חברת Netscape. הדפדפן של Netscape היה מבוסס על "קוד ספאגטי" והפיתוח על בסיס בקוד הקיים היה קשה. גרסה 5 של הדפדפן בוטלה לאחר שהפיתוח שלו התמשך והתמשך ללא תוצאות. ה Technical Debt הגדול הכריע את חברת Netscape והיא החלה לפתח דפדפן חדש מאפס. במקביל היא ביצעה כמה צעדים, נואשים אולי, על מנת להתמודד עם מייקרוסופט, ביניהם תרומה של הגרעין של הקוד שלה לארגון Open Source שהוקם בשם מוזילה (על מנת לאפשר ייצורם של "תואמי Netscape" חינמיים שיזנבו ב IE) ומיזוג לתוך חברת התקשורת AOL.

הפיתוח של Netscape Navigator 6.0 התמשכה והתמשכה והפכה לבדיחה בתעשייה: דוגמה לסכנה הטמונה בפרויקט Next-Generation. מייקרוסופט שחררה בינתיים את IE5 וסיימה את כיבוש שוק הדפדפנים.
Netscape Navigator 6.0 ששוחרר בשנת 2000 כבר איחר את המועד ולא הצליח להתרומם. מייקרוסופט מחצה את התחרות.

נתח השוק של דפדפנים בין 96 ל 2009. מקור: wikipedia

עם נתח שוק של בערך 90% מייקרוסופט לא ראתה אף אחד ממטר. היא הגדירה הרחבות לא סטנדרטיות ל HTML, DOM ועוד ועודדה את המפתחים בעולם להשתמש בהם. ניתן להניח שזו הייתה דרך לבצע "Lock-In" של המפתחים ל IE.
בנוסף לכך, מייקרוסופט לא הצטיינה בהצמדות לסטנדרטים. אמנם הדפדפן שלה היה עדיף על זה של Netscape - אך עושר ה Features הוא מה שיצר את הייתרון - לא הדיוק בסטנדרט. נוצר בפועל סטנדרט חדש: "כמו-IE".

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

הנה דוגמה מפורסמת: לתיבה ב HTML (נאמר, אלמנט div) יש רוחב וגובה. ניתן להוסיף לתיבה margin ו padding - שהם ריווחים מבפנים ומבחוץ, וגם מסגרת בעלת עובי. אם קבעתי תיבה ברוחב 100 פיקסלים והוספתי לה מסגרת בעובי 2 פיקסלים (מכל צד) - האם היא תתרחב לרוחב כולל של 104 פיקסלים, או האם התוכן בתוך התיבה יצטמק ל 96 פיקסלים? זה עניין של פרשנות. המתכנתים של מייקרוסופט ושל Netscape פירשו זאת בצורה שונה.

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

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

זוכרים את הקוד ש Netscape תרמה לארגון מוזילה? ארגון מוזילה המשיך, בשקט בשקט, לפתח את הקוד ובשנת 2004 מוזילה שחררה דפדפן חדש בשם פיירפוקס (שועל האש). פיירפוקס הכיל חידושיים אמיתיים בחווית הגלישה, כשהבולטים בהם הם השימוש בטאבים והקלות בפיתוח Plug-Ins. מייקרוסופט מצידה נרדמה בשמירה והצהירה ש FF לא מהווה איום עליה. רק בגרסה 3, בערך (שנת 2008), FF היה מספיק בוגר ומהיר על מנת שייחשב כעליון על IE6. אחד המאפיינים הבולטים שלו היו מהירות גבוהה, מהירות שגרמה ל IE6 להראות כמו מוצר שנזנח במשך חצי עשור.

נראה שמייקרוסופט התעוררה בסוף 2007, כשגרסאות בטא של FF3 היו זמינות בשוק - והיתרון של FF היה ברור. היא הסירה את הדרישה לבדיקות רישיון חוקי (Windows Genuine Advantage) כתנאי להתקנת IE7 (כל הישראלים היו תקועים עד אז עם IE6) והעירה את צוות הפיתוח שלה מתרדמת ארוכה והחלה לפתח את IE8 במרץ. IE8 סיפק תמיכה טובה בהרבה מ IE7 בסטנדרטים (כלומר: תמיכה סבירה) ומייקרוסופט ניסתה את מזלה ביצירת חווית גלישה חדשה בעזרת  ה Accelerators - ניסיון שנכשל.
ה Popup המעצבן הזה היה אמור להיות החוויה החדשה של גלישה בווב. למרות שנכשל חרוצות - אני עדיין מעריך את מייקרוסופט על שניסו.
מוזילה, בניגוד למייקרוסופט, הייתה קפדנית מאוד בהצמדות לתקנים. היא חרטה את התאימות לתקנים על דגלה והצליחה להביך את מייקרוסופט לא פעם. המשתמשים בחרו בפיירפוקס כיוון שהיה מהיר יותר, נוח יותר ומגניב יותר - אך הדיון בצורך בתקנים והתאמה של אתרים לדפדפנים שאינם IE חזרה לתודעה הכללית.
IE6, וכל גרסאות IE שיצאו אחריו, עדיין מאפשרים להריץ דפי אינטרנט בדיוק כפי שרצו על IE5.5 - דפדפן משנת 2000. למייקרוסופט הייתה חשובה התאימות לאחור והיכולת להריץ כהלכה דפי אינטרנט ישנים. מוד הרצה זה נקרא "Quirks Mode". הוא זמין רק על גבי דפדפני IE, למרות שאופרה ו FF מספקים Quirks Mode Emulation (בקיצור QME) - מצב שבו דפדפנים אלו מציגים "בקירוב" דפים ישנים של IE.

עד היום FF הוא הדפדפן המחמיר ביותר בהצמדות לתקן. אפילו Chrome "מוכן לוותר לפעמים למפתחים". הנה דוגמה פשוטה: URLs לתמונות בתוך קבצי CSS מחושבים יחסית למיקום של קובץ ה CSS. פיירפוקס לא יאפשר לנהוג אחרת. ספארי, כרום וIE ינקטו גישה מקלה ואם הם לא מוצאים את התמונה במקום המצופה, הם ינסו שוב בהנחה שה URL הוא יחסית לדף ה HTML - טעות נפוצה של מפתחים. האם הקלה בתקן היא דבר טוב? היא חוסכת מהמפתחים לתקן את הקוד שלהם - אך מאפשרת יצירה של דפי אינטרנט לא תקניים. A Tradeoff.


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

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

1. מייקרוסופט משחררת דפדפנים לאט. לאחרונה עדכנה את המדיניות שלה לעדכון פעם בשנה - צעד מהפכני מבחינתה. אולם, פיירפוקס וכרום משחררים גרסה כל 6 שבועות, והמשתמשים שלהם משפרים את יכולות הדפדפן שלהם כל הזמן. בין שחרור גרסה לגרסה של מייקרוסופט - משתמשי כרום וFF יעדכנו את הדפדפן שלהם 9 פעמים בממוצע ויהנו במשך תקופה מעוד ועוד תמיכה ב HTML5. 
תאימות של דפדפנים ל HTML5. מקור: html5test.com
2. בעוד כרום ופיירפוקס מעדכנים את גרסת הדפדפן אוטומטית, IE יתעדכן רק בעקבות הסכמה מפורשת של המשתמש.
בנוסף לזאת, IE מציבה קשיים בעדכון של גרסאות חדשות: אם אתם רוצים את IE9 עליכם להיות בעלי Windows Vista SP2 ומעלה. עבור IE10 תאלצו להיות בעלי Windows 7 ומעלה.

הווה אומר: משתמשי Windows XP, שהם עדיין רוב משתמשי ה Windows בעולם, לא מסוגלים לשדרג ל IE9 - הדפדפן הראשון של מייקרוסופט שניתן לייחס לו תמיכה סבירה ב HTML5. מצד שני, אין להם בעיה להשתמש בגרסאות האחרונות של כרום או פיירפוקס - מה שמצביע שההחלטה של מייקרוסופט נובעת משיקולים עסקיים. נראה שIE נדרש "לדחוף" שדרוגים של מערכת ההפעלה Windows, ואינו חופשי להתחרות בצורה "חופשית לחלוטין" מול הדפדפנים האחרים.

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

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

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

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


Internet Explorer 10
אז אולי למייקרוסופט לא יהיה את הדפדפן הנפוץ או הטוב ביותר בשוק - מה הבעיה?
  • פגיעה במנוע החיפוש Bing. גם כאשר הוא מנוע החיפוש המסופק כברירת מחדל ב IE, משתמשים שונים מחליפים אותו ל Google. פחות חיפושים => פחות הכנסות מפרסום.
  • מוצרים רבים של מייקרוסופט הם מוצרי ווב. למשל: Office 365 ו Azure. הבעלות על דפדפן, והיכולת לקדם "סטנדרטים" בדפדפנים הם רוח גבית שמסייעת לשלמות של פתרונות הווב של מייקרוסופט. מגמה של אתרים שיפסיקו לתמוך ב IE, אם תהיה כזו, תפגע קשה ביכולת של מייקרוסופט לקדם מוצרים בעזרת הדפדפן.
  • Windows 8 הופך להיות מבוסס ווב ו JavaScript. השינוי הארכיטקטוני הגדול של מייקרוסופט ב Windows Vista (שהיה אסטרטגי, אך לא עניין את המשתמשים) היה לעבור ל Kernel מצומצם יותר ולהפוך את ה CLI (ה virtual machine של .NET) לסביבת ההרצה העקרית של Windows. חזון יפה ושאפתני.
    אבל מאז מחשבי הטאבלט הפכו למציאות ארגונית בה למייקרוסופט אין כרגע נוכחות. ההשקעה בפתרונות התלויים ב.NET ולא יכולים לרוץ על מחשבי טאבלט של אפל או אנדרואיד היא החלטה מגבילה למדי עבור ארגונים רבים. מייקרוסופט נאלצה להתכופף ברגע האחרון ולהפוך את JavaScript ו HTML5 ל "First Class Citizens" של Windows 8, אולי אפילו על חשבון טכנולוגיות .NET (נוכל לדעת זאת עם הזמן). הדבר העצוב עבור מייקרוסופט הוא ש IE10 שיתמוך באסטרטגיה הזו עתיד להיות בעת השקתו דפדפן בינוני למדי - יחסית לשאר הדפדפנים הזמינים [ג].

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

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



----

קישורים רלוונטיים:
ההיסטוריה של אינטרנט אקספלורר (מפורט)

----

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

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

[ג] מייקרוסופט תטען אחרת, כנראה. אחד הגורמים שבהם מייקרוסופט מנסה "למכור" לנו את העליונות של IE10 היא בדיקות ביצועים של Canvas (כתיבה ישירה ל"מסך") ו WebGL. דפדפן IE אכן נהנה מיתרון בכל הנוגע ל Hardware Acceleration במערכות Windows - אך זה רק מימד אחד ולא כ"כ קריטי לדעתי.

[ד] הדפדפן הראשון, אגב, נקרא WorldWideWeb ונכתב ב Objective-C - שפה לא-חדשה בעליל.

[ה] הנה תגובתה של מייקרוסופט. http://windowsteamblog.com/ie/b/ie/archive/2012/03/18/understanding-browser-usage-share-data.aspx.


יום שישי, 25 במאי 2012

מבוא מואץ ל JavaScript עבור מפתחי Java / #C מנוסים - חלק 1


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

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


שייך לסדרה מבוא מואץ ל JavaScript ו jQuery



למה JavaScript?
חלקכם אולי עשוי לחשוב שג'אווהסקריפט היא היסטוריה ולכן - השקעה בלימוד השפה איננה פעולה משתלמת.
ג'אווהסקריפט אמנם איננה שפה חדשה (היא הופיעה ב95' ביחד עם ג'אווה) - אך בעוד ג'אווה בדעיכה, ג'אווהסקריפט תופסת תאוצה. אני רואה לכך כמה סיבות:
  • בעוד ה JVM של ג'אווה רץ על "כל שרת" - עובדה שסייעה לג'אווה להפוך למאוד נפוצה, ג'אווהסקריפט יכולה לרוץ על כל פלטפורמות ה JVM (בעזרת Rhino) ובנוסף - גם על דפדפנים ועל iOS -> שתי פלטפורמות אסטרטגיות שחשיבותן רק הולכת ועולה. תאהבו את זה או לא, אבל ג'אווהסקריפט היא שפת התכנות האוניברסלית ביותר שקיימת כיום.
  • ג'אווהסקריפט היא "מונופוליסטית": אין שפה אחרת שנתמכת ע"ג כל הדפדפנים החשובים.
    בניגוד ל JVM וה CLI שמריצים ByteCode ולא מודעים לשפה שבהם ה ByteCode נכתב (וכך נפתח פתח ל JRuby, סקאלה ועוד) JavaScript היא שפה מפוענחת (interpreted) והמנועים של ג'אווהסקריפט שפרוסים על הדפדפנים יודעים להריץ רק אותה.
  • ג'אווהסקריפט טובה לבניית UI. בניגוד לג'אווה שבמשך שנים ניסתה וניסתה - אך נכשלה, בג'אווהסקריפט ניתן לכתוב UI יפה ובצורה קלה. (על בסיס HTML ו CSS - כמובן).
  • לג'אווהסקריפט יש בסיס מתכנתים גדול. הרבה מפתחי #PHP, Ruby, C וג'אווה - יודעים גם קצת ג'אווהסקריפט. יש איזה ייתרון בלהיות שפה זקנה בת 17.
  • לג'אווהסקריפט אין הרבה מתנגדים. אין פה מלחמה בין אורקל למייקרוסופט, בין גוגל לפייסבוק וכו'. ג'אווהסקריפט נמצאת בעין הסערה.

ע"פ ה HTTP Archive, למשל, פרויקט שעוקב אחרת מגמות באתרי האינטרנט הגדולים, כמות הג'אווהסקריפט בשימוש באתרים שבמדגם זינקה ב 50% בשנה האחרונה בלבד.

כמה ג'אווהסקריפט יש בדפי אינטרנט של אתרים מפורסמים? הממ... זה גדל! מקור: pingdom.com


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

טעות מס' 1: "אני מכיר את ה Syntax". זהו C-Syntax. אני אסתדר Along the way.

המציאות: Java ו JavaScript דומים אחד לשני כמו "Car" ו "Carpet": בעיקר בשם.
הקוד הבא אכן נראה מוכר למדי:
for (i = 0; i< set.length; i++) {
  set[i].doSomething();
}
האם אתם יכולים לומר בוודאות באיזו שפה כתוב קוד זה? אני בספק.
אם אתם מדמיינים כך את הג'אווהסקריפט שתתקלו בו - אתם טועים. מהר מאוד תתקלו בביטויים כמו prototype, הסימן $ שמופיע המון, משתנים עם קווים תחתונים __ ובכלל - סגנון זר ולא מוכר. זהו אמנם C-Sytnax - אך יש בו מספיק אלמנטים לא מוכרים על מנת לבלבל אתכם לגמרי.

למשל, האם אתם יכולים להסביר מה עושה הקוד הבא (שכתוב ב C-Syntax)?
Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)));
  };
};


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

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

קחו לדוגמה את האתר W3Schools - אתר reference לטכנולוגיות ווב המוכר. לאתר, מסתבר, אין שום קשר ל W3C והוא התבקש ע"י ה W3C, כמה פעמים, לשנות את שמו. מדוע?
האתר כולל שגיאות גסות בנוגע ל HTML, CSS וג'אווהסקריפט בכלל. אמנם הוא עושה רושם רציני - אך העובדות מדברות בשם עצמן. W3Fools - אתר שאוסף (חלק מ-) השגיאות וחוסרי הדיוקים של W3Schools, ממליץ למשל לחפש בגוגל עם "w3schools-", כלומר: רק תוצאות שלא כוללות את W3Schools. בהסתמך על הפופולאריות של W3Schools וכמות הפעמים שהוא מופיע בגוגל - זו עצה לא כל-כך רעה...


טעות מס' 3: "הבנתי. משהו פה לא עובד. נקרא את התיעוד הרשמי מקצה-לקצה כך שלא יהיו לנו הפתעות".

המציאות: כשלמדתי Java באמת הלכתי ל Spec - אך זו הייתה שפה ראשונה והייתי סטודנט צעיר. כשניסיתי לקרוא את התיעוד המומלץ של ג'אווהסקריפט - מצאתי את עצמי משתעמם מהר מאוד. רוב מה שכתוב שם הוא ברור מאליו למי שמכיר את ג'אווה או #C לעומק.

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

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

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

כמה הבדלים בסיסיים בין JavaScript וג'אווה:
הערה: אני מקצר וכותב "ג'אווה" בלבד, אך מה כתוב כאן רלוונטי באותה מידה ל #C.

Scope
בג'אווה, Scope נוצר ע"י סוגריים מסולסלים, יהיה זה משפט if, לולאת for או סתם סוגריים שהוכנסו בתוך הקוד.
בג'אווהסקריפט Scope נוצר רק על ידי פונקציה. הנה דוגמה להתנהגות הצפויה (מקור: javaScriptGarden):
function test() { // a scope
  for(var i = 0; i < 10; i++) { // not a scope
    // do something
  }
  console.log(i); // 10
}

Global Scope
מה שלא מוגדר בתוך ה Scope של הפונקציה - שייך ל Scope הגלובלי. דריסות הדדיות הן תקלה שכיחה.
// Defined in Global Scope
foo = '42';

// Defined in "current" scope. Either function or global
var foo = '42';

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

הנה דוגמה מרגיזה: כתבתם אפליקציה לניהול חתונות. נשיא וארה"ב ואשתו אישרו הגעה. הפקיד ראה הודעות Alert ברורות של אישור ההשתתפות על מסך-המחשב, אבל המקומות לא נשמרו והם נאלצו לאכול בעמידה (כלומר, הורי החתן נאלצו לאכול בעמידה - כמובן).
weddingParticipantsCounter = 100;

function acceptParticipation(name) {
weddingParticipnatsCounter = weddingParticipantsCounter + 1;
alert('Registration Accepted: ' + name);
}

acceptParticipation("Mr. President");
acceptParticipation("The First Lady");
console.log(weddingParticipantsCounter); // -> 100?!
האם אתם יכולים להסביר מה השתבש? [א]

איך מתמודדים עם pitfall שכזה שבנוי בתוך השפה? כלי וריפיקציה בשם JSLint יספק הזהרה, אם אתם עובדים ב IDE שמריץ אותו תוך כדי כתיבה - יש סיכוי שתצליחו להימנע מכמה תקלות. הבעיה ב JSLint (או חברו JSHint) הוא שההזהרות שהם מספקים נכונות רק ל 90% המקרים ואתם נשארים עם רשימה של Warnings לא מטופלים - גם כאשר יש לכם קוד נפלא.
CoffeScript היא דרך נוספת להתמודדות. הוא לדוגמא מוסיף var מאחורי הקלעים לכל הגדרה.

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

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

התבוננו על דוגמת הקוד הבאה:
var n = 1;
function foo() {
    if (false) { var n = 10; }
    console.log(n);
}
foo();
מה אתם מצפים שתהייה התוצאה שתכתב ללוג?
זו כמובן דוגמה מופשטת שיכולה לתאר מצב אמיתי ומורכב הרבה יותר. דמיינו את הקושי לאתר תקלות שכאלו בקוד של עשרות של שורות עם לוגיקה מורכבת.

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

הקוד שבעצם רץ, לאחר פעולת ה hoisting, הוא זה:
var n;
function foo() {
    var n;
    if (false) { n = 10; }
    console.log(n);
}
n = 1;
foo();
הגדרת המשתנה n, גם בתוך הפונקציה, עולה למעלה. זכרו שהסוגרים המסולסלים של משפט ה if לא מגדירים Scope חדש. כחלק מחוקי ה hoisting, ההשמה נשארת במקומה.
n מוגדר ב scope של הפונקציה ולכן הוא "מחביא" את n שהוגדר ב global scope.
כיוון שהתנאי "false" לא מתרחש במקרה זה, n נשאר undefined עד לנקודה בה הערך נכתב ללוג.

מה עושים? 

שומרים במשמעת ברזל על הכלל הבא:
  • כל הגדרות ה var וה function יהיו תמיד בראש ה scope הנוכחי, אם זה הקובץ (גלובלי) או הפונקציה.

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

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

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

אם כן - זה יכול להיות Case Study טוב ב Pre-Sale. אני מניח שלא מעט תוכנות ארגוניות נהנות מהמנגנון הזה.


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

אני יודע (ע"פ סטטיסטיקות של Google Analytics) שאם אתם קוראים את הבלוג הזה יש סיכוי של 50% שאתם משתמשים בכרום, ועוד כ 20% שאתם משתמשים ב FireFox. לשני הדפדפנים הללו יש סביבת פיתוח לא רעה בכלל לג'אווהסקריפט שניתן להתחיל להשתמש בה מיד. אם אתם עדיין תקועים עם IE - השיגו לכם כרום. הגיע הזמן.

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


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


אובייקטים ופונקציות

Object Literal
{};
כך יוצרים בג'אווהסקריפט אובייקט. זהו אובייקט ריק.


בפועל אובייקט הוא רשימה של תכונות:
var myObj = { a: "Hello", b: "World" };
אם התחביר נראה לכם מוכר, נסו להיזכר מהם ראשי התיבות של JSON. הא!

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


פונקציות הן אובייקטים
בג'אווהסקריפט, פונקציות הן אובייקטים לכל עניין ודבר. על כן, אין לי מניעה לכתוב את הקוד הבא:
function foo(text) { console.log(text); }
foo.x = 4;
foo(foo.x);
שידפיס כמובן את הערך 4.


Anonymous Functions
ג'אווהסקריפט בדפדפן היא שפה עשירה מאוד בשימוש בevents ולכן התחביר של Anonymous Functions הוא קצר ונוח. לדוגמה:
obj.doSomething(function(event) { console.log(event.getMessage()); });

הדרך המומלצת להגדרת פונקציות בג'אווהסקריפט היא להגדיר פונקציות אנונימיות ולבצע השמה למשתנה:
var foo = function(text) { console.log(text); };
בלינק זה תוכלו למצוא כמה דוגמאות מה יכול לקרות לכם אם לא תעשו זאת (מוהא-הא-הא!).

על מנת למנוע דריסה של פונקציות, אפשר להשתמש ב namespace:
var myNS = myNS || {}; // if namespace myNS exists - use it, else create a new namespace.
myNS.foo = function(text) { console.log(text); };


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

כאשר יש פונקציה בודדת, המשתנים שלה ימחקו מייד לאחר הרצת הפונקציה:
function simpleFunction() {
  var x = 4;
}
// x no longer exists

כאשר יש לי פונקציה פנימית, בתוך הפונקציה, שקוראת למשתנים - הם ישארו לחיות לעד. אני מנחש שזה עניין של pointer counting. הנה דוגמה:
function Counter(start) { // closure

  var count = start;
  return function() { // function with scope
      return ++count;
  }
}

var c = Counter(4);
// count still exists
c(); // 5
c(); // 6
המשתנה c מחזיק reference לפונקציה הפנימית של Counter, והיא מצידה מחזיקה reference למשתנה count - וכך הוא נשמר בחיים. 

בואו נסתכל בדוגמא לבעיה שיכולה להיפתר ע"י שימוש ב Closure.

בדוגמת קוד תמימה זו, אני משתמש ב anonymous function מהסוג שהזכרנו קודם לכן על מנת לממש Listener. זוהי פעולה נפוצה למדי בג'אווהסקריפט. אני מגדיר פונקציה פשוטה למדי שתכתוב לערכים לlog.
התוצאה הצפויה היא, אם כן, ספירה מ 1 עד 15 ל log.
var listeners = []; // array

// fill up some listeners
for (var i = 0; i < 15; i++) {
  listeners.push(function() { console.log(i); });
}

// trigger an event to all listeners. Each one counts.
for (var j in listeners) {
  listeners[j](); // execute
}
התוצאה בפועל היא 15 פעמים המספר "15".
הסיבה לכך היא כזו: הפונקציה שנוצרת בתוך לולאת ה for מתייחסת למשתנה i, אבל i הוא משתנה בסביבה הגלובלית. נזכיר שסוגריים מסולסלים לא מייצרים scope. בנוסף - הפונקציה אינה מחושבת בזמן ההגדרה, אז בפועל נוצרות לנו במערך ה listeners חמש עשר עותקים של פונקציה שתוכנן הוא (console.log(i.

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

הדרך לפתרון היא להוסיף Closure שישמור (או "יקפיא") את ערך המשתנה i, עבור הרגע בו הוגדרה הפונקציה:
var listeners = []; // array

function eventHandler(i) { // outer function = closure
  return function() { // inner function
    console.log(i);
  }
}

// fill in the listeners (syntetic)
for (var i = 0; i < 15; i++) {
  listeners.push( eventHandler(i) );
}

// trigger an event to all listeners. Each one counts.
for (var j in listeners) {
  listeners[j](); // execute listener
}
בדוגמה זו, הפונקציה eventHandler מבוצעת בתוך הלולאה. הערך i עובר אליה כפי שהוא, ואז נלכד "לנצח" בתוך ב closure. טוב, לא ממש לנצח - אולי עד שנגלוש לדף ווב אחר.

הפונקציה שנשמרת במערך listeners היא כבר הפונקציה הפנימית והרצתה תגרום לכתיבת הערך המצופה, קרי 0 עד 14.

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


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

מקווה שנהניתם!


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


---

[א] קצת אכזרי, אך זו מהמציאות: weddingParticipnatsCounter = weddingParticipantsCounter + 1. ג'אווהסקריפט זיהה משתנה לא מוכר ובמקום להטריד את המתכנת - טרח והגדיר אותו בשבילו. איזה יופי!
IDE טוב היה מספק value highlighting שאולי, היה יכול לעצור מוקדם את התקלה.

[ב] האם זו טעות תכנונית שתעלה למשק העולמי 2 מיליארד דולר?




יום רביעי, 16 במאי 2012

בית קברות לסטארטאפים: The Chasm


דיסקליימר: ה Chasm מכה גם במוצרים בחברות גדולות. הכותרת היא לשם הקריאות בלבד.

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


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

כיצד ניתן להסביר סירוב שכזה?!
באים אל החוואי ונותנים לו מתנה משמיים - אך הוא מסרב?!

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

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


מחזור קבלת טכנולוגיות (Technology Adoption Lifecycle)
סדרת המחקרים הניבה תוצאות עקביות[1] וכך החוקרים הצליחו לבנות מודל שמתאר בצורה טובה את המתרחש.
המודל חילק את החוואים לחמש קבוצות של אנשים, בהיבט קבלה של טכנולוגיה חדשה:
סוגי הלקוחות בהיבט האימוץ של טכנולוגיה חדשה. מקור: "The Diffusion Process", Special Report No. 18 (Agriculture Extension Service, Iowa State College) pages: 56–77
באפון קלאסי, האנשים הראשונים לאמץ טכנולוגיה חדשה הם אלו שמעריכים אותה בזכות מה שהיא.

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

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

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

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

אחוז גדול יותר של החוואים, 10-15% מהם, נקרא מובילי שוק (Early Adopters). אלו הם לרוב החוואים משכילים, דינאמיים ופתוחים לשינויים. הוא יהיה מוכן לנסות ולאמץ את הטכנולוגיה החדשה ולראות האם היא מצליחה. הוא נהנה מהערך החברתי בלהיות חדשן ו״לפני כולם״, אבל המסירות שלו לרעיון היא פחותה משל החוואי החדשן. לרוב הוא יצפה למחיר נמוך או הטבות תמורת נכונותו ״להתגלח״ על המוצר החדש והוא יסכים לקבל מוצר לא כל-כך בשל.

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

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

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

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


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

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

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

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


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

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

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


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

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

הסדק הזה קיבל כבר שם היאה לכבודו: "התהום", The Chasm.


Liberty Bell - סמל אמריקאי ואולי מקור ההשראה של מור לתיאור "הפעמון הסדוק". מקור: http://etc.usf.edu


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

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

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


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

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


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

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


Crossing The Chasm
בעוד קצת אינטואיציה ומזל יכולים לעזור לכם לעבור את ה"סדקים" האחרים, המעבר את התהום דורש טקטיקה מדויקת, תכנון והבנה. הפעם בין "מובילי השוק" ל"early majority" הוא פשוט גדול מדי מכדי שהמעבר יתרחש מעצמו.

ישנה דרך מומלצת לחציית התהום. נוסחה. קל לדבר וקשה לעשות. היא הולכת כך:
הבעיה הגדולה שלכם היא שלקוחות "Early Majority" ירצו references. דוגמאות ללקוחות, עדיף שדומים להם בגודל ובתעשייה בה הם עוסקים (לדוגמה כימיה, רו"ח, חברות תעופה וכו'), שימליצו ויספרו על ההצלחה. לקוחות ה Reference נדרשים להיות "Early Majority" בעצמם. כיצד ניתן לפרוץ את המעגל ולהגיע ללקוחות ה Reference הראשונים?

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

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

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

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

איש מכירות מחברת ABC (השם שמור עמי) סיפר לי את הסיפור הבא:

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


פלישה רצינית: נורמנדי.

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

מצד שני ספרים אני קונה שבוע אחרי שהם יוצאים. היו תקופות שהייתי משוטט בחנויות ורק סורק את הספרים החדשים למצוא כאלו שנראים לי. יצא לי כבר לקרוא כמה ספרים (בעיקר מקצועיים) ב beta או MEAP ואפילו לתרום ל Errata או לדיונים בפורום. אני אוהב להמליץ לאנשים אחרים על ספרים ואני מקבל אי-החזרה ארעית כמחיר סביר להנאה זו. האם אני Innovator?

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

אני אשמח לשמוע תובנות נוספות בנושא.



-----------

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

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

[3] "המכנה המשותף לתעשיית הסמים ולתעשיית התוכנה הוא שבשניהם מכנים את הצרכן בשם 'משתמש'" - ציין איתמר טאייר. אהבתי!


יום רביעי, 9 במאי 2012

סיבוכיות: מקבלים את זה בחינם

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

כמה פשוט וקל לדבר על פשטות:
  • "בואו נעשה את זה פשוט"
  • Keep It Simple, Stupid
  • Less is More
כמה קל!!

אבל מה היא פשטות, ואיך משיגים אותה?


מה שמעון פרס היה אומר?

פשטות דומה ל"שלום עולמי" - אי אפשר להתנגד אליה.

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

הקונצנזוס החיובי לגבי פשטות - הוא אוניברסלי.

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

...מתי אמרתם שיוצא הספר "World Peace for Dummies"?


מקור: http://everydaybipolar.wordpress.com/

ג'ונגל הסיבוכיות

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

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

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

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

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

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





עיקרון #2: החכמה היא להאריך את הדרך אל הג'ונגל, עד כדי כך שאולי אפילו לא להגיע אליו...

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

"אנחנו מקבלים את זה בחינם", או חוסר ההבחנה בין ממשק public ל published.
נאמר שהיה לכם צורך לבצע חיפוש על שני סוגי אובייקטים במערכת. בגלל שמספר המקרים גדול מ - 1, כתבתם קוד כללי שמבצע חיפוש על n אובייקטים במערכת - הנדסת תוכנה טובה. השלב הבא הוא לומר לכולם (תיעוד, תהליכים או סתם המלצה - תלוי בארגון): יש לנו חיפוש - תשתמשו בו.
אפילו יותר גרוע: תחשפו UI, WebService או Public API שלקוחות יוכלו להשתמש בו: הרי הקוד שם - וכך אתם יכולים בעלות נמוכה להשיג תועלת גבוהה - כלכלה פשוטה, "מקבלים את זה בחינם".

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

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

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


"ריבית דריבית"
אם תכפילו 1.2 חמש פעמים תקבלו יותר מ 2. משהו כמו 2 וחצי. החצי הוא ה"ריבית דריבית".
אם תוסיפו פיצ'ר של חיפוש, ועליו יכולת Customization ועליה יכולת X ועליה יכולת Y - הפיצ'ר הבא (נקרא לו "Z"), יהיה יקר יותר מאשר המקרה בו הייתם נמנעים מלהוסיף את יכולות X ו Y. לעיתים - ההבדל בסיבוכיות המערכת הוא משמעותי למדי.

זכרו את הכלל הבא: העלות של יכולת חדשה n היא זמן הפיתוח של n + זמן התחזוקה של n + זמן גבוה יותר לפיתוח יכולת n+1 וזמן תחזוקה גבוה יותר ליכולת n+1. רקורסיבית (lim: n-->m).
עקרון שהתייחסתי אליו גם בפוסט על היעילות האמיתית שב SCRUM: הדרך הטובה ביותר לפריון גבוה יותר בפיתוח הוא לייצר פחות פ'יצרים - וכמעט תמיד יש מה להוריד. YFAGNI[ב]!


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

הייתה לי פעם שיחה עם איש UX שאני מאוד מעריך. מדוע ה UI של המערכות שלנו הוא לא "כזה מגניב" - למרות שאנו באמת מנסים ומשקיעים.
"למה שיצא לנו UX מגניב?" - הוא שאל בתמימות.
"כי אתה ממש תותח...?!" - עניתי.
"האא... זה לא עובד ככה..." הוא החל להסביר. הוא הסביר שלא ניתן לקלוע ל UX מצוין בפעם ראשונה, אפילו איש UX מוצלח. הדרך להגיע לשם היא ע"י השקעה באיטרציות:
  1. תכנון ה UX
  2. בדיקת שימושיות (על משתמשים אמיתיים)
  3. הפקת לקחים - ותכנון שיפורים
  4. וחוזר חלילה
רק לאחר איטרציה ועוד איטרציה ועוד איטרציה - ה UX מתחיל להיות באמת אפקטיבי, "זורם", ומהנה. (רעיונות דומים אגב מתכנסים היום תחת התחום שנקרא כיום "LEAN UX", למשל לעשות usability tests מאוד קטנים, אבל כל ספרינט).

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

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





-----

[א] הערה טכנית: כמובן ש Unit Tests ואוטומציית רגרסיה היא גיבוי רב-עצמה לביצוע שינויים כאלו בפועל.

[ב] ! You Ain't Gonna Need It