2017-08-17

קוטלין (Kotlin) למפתחי ג'אווה ותיקים - חלק ה': DSLs

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


אחד החלקים המתקדמים בשפה (באופן טיפוסי בשפות-תכנות?) הן היכולות לייצר DSL - כלומר: Domain Specific Language.
DSL היא "תת-שפה" המשמש בחלק מהמערכת לתיאור יעיל יותר של Domain מסוים. למשל: תחביר לייצור JSON, לגישה לבסיס הנתונים, לניהול חוקים עסקיים, תיאור UI, וכו'.

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

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

ראינו את ה DSL המוגבל של ג'אווה,  ו DSL ... גרוע (ודמיוני) של Enterprise Java. כיצד נראה DSL יותר מרשים?

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

מעוז סמלי של יכולות ה DSL של גרובי הוא כלי הבילד Gradle - מפתחי ג'אווה רבים (ברובם אנדרואיד?) משתמשים ב DSL של Gradle בכדי להגדיר build scripts פשוטים, ויעילים - תוך כדי שהם נהנים מבדיקת-התחביר של הקומפיילר.

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

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

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

הנה רשימת "יכולות ה DSL" העיקריות של קוטלין:


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


ברוכים הבאים לעולם היפה והמתעתע של הגדרת DSL 😄





Infix Functions 


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


אפשר להפעיל את המתודה foo על האובייקט A בתחביר רגיל (1) - או מקוצר.
התחביר המקוצר אפשרי רק כאשר הפונקציה מוגדרת כ infix, ו modifier של infix ניתן להוסיף לפונקציה רק כאשר היא מקבלת פרמטר בודד.

מתי זה שימושי?
זה יותר שימושי על טיפוסי בסיס: String, Boolean, וכו'. הנה דוגמה מ KotlinTest:


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

כאן באה לידי ביטוי יכולת חשובה של השפה בשם Extension Functions.


Extension Functions


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

קוטלין הושפעה מיכולת של שפת #C בשם Extensions Methods - ויצרה יכולת דומה הנקראת Extension Functions. אפשר פשוט להרחיב מחלקה, מבחוץ - מבלי "לפתוח" אותה:


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

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

  1. הנה הפעלה של extension function ל String - בתחביר הרגיל.
  2. הנה הפעלה בתחביר ה infix. רצף הקריאה הוא קולח יותר.
  3. נשלב את הקריאה לפונקציית למבדה.
  4. ניתן לשרשר קריאות infix אחת על השנייה.
    1. הרחבתי את האב הקדמון Any להכיל מתודה thenAdd - שתהיה זמינה לכל אובייקט בשפה.
    2. לא כל מה שאפשר להגדיר כ "DSL" הוא באמת קריא יותר: זו דוגמה לרצף קריאה מבלבל, שכנראה רק מי שהגדיר את ה DSL - יבין...

כדי לא לבלבל, כדאי להקפיד על הכללים הבאים בעת הגדרת infix functions:
  • על שם הפונקציה להיבחר בקפידה - עבור רצף הקריאות (readability flow). לא לבלבל ולא להפתיע.
  • אם אתם מתכננים לשרשר קריאות Infix נסו שהטיפוס יישמר, ולא לעבור בין טיפוס א' (Boolean) לטיפוס ב (מחרוזת) - כמו בדוגמה (הרעה) למעלה.
  • אל תזרקו exceptions מתוך infix functions.
    • infix function נראית כמו מילה שמורה בשפה - והמשתמש לא יצפה לאפשרות של exception (כפי שהוא לא מצפה ממילה שמורה בשפת קוטלין)

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

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

יש. הנה הם לפניכם:

  1. יצרנו מחלקה עם המתודה ()foo - ואז הרחבנו אותה. "מי תיקח"?
  2. בקוטלין יש כלל מאוד ברור: member תמיד קודם ל extension function
    1. אתם אולי יכולים לראות של ()C.foo - יש warning ב IDE שאומר: הפונקציה הזו מוחבאת ע"י ה member - ולעולם לא תוכל להיקרא. 
  3. עכשיו יש לנו 2 מחלקות היורשות זו מזו: B יורשת מ A. לכל אחת - הרחבה שונה לפונקציה foo.
  4. הכלל בקוטלין הוא שה resolving ל extension function הוא סטטי: ממשק האובייקט יקבע איזה פונקציית הרחבה להפעיל בפועל - ולא טיפוס האובייקט בפועל.
    1. הנה דוגמה: הפונקציה ()printFoo מצפה ל A (ממשק), אך מקבלת מופע של B (טיפוס האובייקט בפועל). מכיוון שה resolution הוא סטטי - בודקים אם ל A יש פונקציית הרחבה, ומכיוון שיש - מפעילים אותה.
  5. כאשר אין הרחבה לטיפוס / ממשק נתון - מחפשים בעץ ההיררכיה את המחלקה הראשונה שיש לה הרחבה מתאימה.

ניתן להגדיר extension functions גם על nullable types - מה שמאפשר להפעיל את הפונקציה גם כאשר הערך של האובייקט הוא null:


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


Extensions, extensions, extensions


Extension Properties


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


כלומר: לא ניתן להוסיף initializer ולאתחל את הערך של extension property.
כן ניתן להגדיר את התכונה כ var, ולהוסיף לה setter.







Extension Functions הן כלי חשוב, אבל הן גם מועדות לשימוש-יתר.

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

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


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

fun String.toJson()

מול

fun UtilsClass.toJson(string)

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

בקיצור: פה אתם משמשים ככלי העיקרי לבחירות מושכלות ובעלות רגישות.




Lambda Extension Functions (או: Lambda with receivers)


היכולת של פונקציות הלמבדה, לא לציין במפורש פרמטר יחיד, ולהראות כמו קינון - הוא בעל פוטנציאל DSL-י:


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

את היכולת הזו משלימים עם היכולת להגדיר receivers לפונקציות למבדה - מה שהופך אותן בפועל ל extension (lambda) functions:

  1. נפתח את הדוגמה בהגדרת מחלקה בשם RoutingMap. בשלב הזה - זהו בעצם alias. דמיינו שיש יותר.
    1. נ.ב: אם באמת הכוונה שלנו היא רק להציע alias - הצורה האידיומטית (idiomatic) לעשות זאת בקולטין היא בעזרת המילה השמורה typealias:
    2. מה שנחמד ב typealias הוא שאפשר להשתמש בו מול מחלקות שהן final - שלא ניתן לרשת אותן, כמו String או Int.
  2. אני יכול להגדיר DSL, בעזרת הגדרת פונקציה שמקבלת כפרמטר פונקציית למבדה.
  3. הנה ההפעלה: הפונקציה route:
    1. יוצרת RoutingMap.
    2. מפעילה את הלמבדה ("צריכת התוכן" ב DSL)
    3. רושמת את ה routes במקומות השונים, או במקרה שלנו - מדפיסה את ה map.
  4. בעזרת פונקציית למבדה עם receiver - הקוד יכול להראות נקי יותר.
  5. הנה ההפעלה של הפונקציה (route(2:
    1. יוצרת RoutingMap.
    2. שימו לב להבדל: בזכות ה receiver - בעצם הלמבדה מרחיבה (משמשת כ extension function) את מחלקת ה RouteMap - ולכן אנו פשוט מפעילים את הפונקציה של המחלקה.
      כמובן שההרחבה הזו טובה רק ל scope של פונקציית ה route2 - ולא מעבר לה.
    3. רושמת routes / מדפיסה.
  6. התחביר של פונקציית הלמבדה עשוי להראות מעט מוזר -  בואו נפרש אותו:
    1. התחביר הוא בעצם : <Receiver Type>.(<Param types>) -> <Return Type>
    2. לדוגמה: String.(Int, Int) -> Int
      אנו מרחיבים את המחלקה String, בעזרת פונקציית למבדה שמקבל שני פרמטרים מסוג Int ומחזירה Int.
    3. בד"כ / בפונקציות למבדה "רגילות" - פשוט אין Receiver.
    4. בדוגמה שלנו - פשוט אין לפונקציה פרמטרים.


רוצים להקדם קצת יותר ב DSL? - הנה שתי תוספות שניתן לעשות:
  1. אפשר להחליף את השם set לשם נוח יותר: למשל: addRoute - ע"י הוספת פונקציה ל RoutingMap שרק עושה delegation ל set.
  2. אפשר אפילו להרחיב את הביטוי כולו כדי שהיה "בשליטתנו". בדוגמה הבאה (הזריזה) החלפתי את ה Map ל ArrayList של Pairs משלי כדי להגדיר את respondWith עליו.
    1. יכולתי להרחיב את Any - אבל זו פרקטיקה רעה למדי. דמיינו אלו תקלות יכולות לקרוא שמישהו מוצא ב autocomplete פונקציה בשם שנראה לו הגיוני.
    2. מצד שני, אני לא בטוח שהפתרון של MyPairs הוא מוצלח גם כן: ויתרתי על יכולות ה hash של ה HashMap. כאמור: זו לא המלצת מימוש - רק משחק ביכולות של שפת קוטלין.




הרחבה אחרונה: אני רוצה לבנות מבנה מקונן, בו יש type safety ל response.

בדוגמה הבאה שיניתי כמה שמות - לצורך קריאות הקוד.
MyPair הוא בעצם RouteEntry. עברנו את השלב להסביר שהוא מחזיק בעצם זוג משתנים.
RoutingRegistry הוא לא באמת Map - אז לא נכון להצהיר עליו ככזה.
את HttpStatus - המחלקה המקוננת המתארת את ה response, יצרתי כ data class. ב RouteEntry דרסתי את toString בעצמי.

בסופו של דבר, הגענו לקוד יותר "DSL-י". כזה שאולי היינו שמחים לעבוד איתו להגדרת routes ב Web Framework:




Operator Overloading


Operator Overloading היא היכולת להגדיר התנהגויות של Operators (+, -, ==, וכו') למחלקות שלנו. למשל:


  1. בחרתי במחלקה דיי פשוטה: data class. 
  2. האופרטור + הוא בעצם המימוש של הפונקציה plus, והאופרטור * - של הפונקציה times
  3. ההפעלה של a+b היא דיי ברורה, אבל מי החליט מהי מחרוזת כפול מחרוזת?
    1. פה מתגלה הסיכון הגדול של שימוש ב Operator overloading: בניית סמנטיקה לא-צפויה.
    2. בכלל בהגדרה של DSL, לסמנטיקה ולמינוח המדויק - יש חשיבות רבה. בדריסת אופרטורים - על אחת כמה וכמה: חשוב מאוד לבחור סימן שיתאר התנהגות צפויה, גם ליישות =! self, גם למי שלא קורא את מימוש האופרטור.


בניגוד לסקאלה, לא ניתן להגדיר בקוטלין כל סימן אפשרי כאופרטור.
אולי אפשר להבין ש אבא + אבא = סבא, אבל מה זה לעזאזל אבא £ אבא, או אבא ^_^ אבא? (כל אלה אפשריים בסקאלה).

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



Destructing Operator


אופרטור מיוחד אחד של קוטלין הוא ה destructing operator ("פירוק המבנה"?).

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


נתחיל במילה הקצת מוזרה to המשתמשים בה להגדרה inline של Maps:


הא! זה "כולה" infix function, שעושה הרחבה (extension) לכל טיפוס (?Any) שייקרא A, עם פרמטר יחיד מכל סוג (?Any) שיקרא B - ומחזירה Pair של שניהם.
השורה:

val x = null to null

היא אם כן, ביטוי לגיטימי השומר במשתנה x אובייקט Pair עם שני nulls.
פשוט!

מה משמעות התחביר (char, index) אומר?
זו פעולת destructing declaration המציבה ערכים בשורה של משתנים (v1, v2, …​, vn) באופן הבא:

v1 = <T>.component1()
v2 = <T>.component2()
...
vn = <T>.componentn()

לדוגמה:


מאיפה מגיעות הפונקציות ()component1 ו ()component2?

זהו פשוט operator overloading שנעשה במחלקה Pair, מה שנקרא deconstructing operator.

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


Invoke


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


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

פונקציות למבדה בקוטלין, מיוצגות בעצם כאובייקט Function המממש אופרטור ()invoke. מכיוון שזה אובייקט, ניתן להעביר אותו לפונקציה כפרמטר, לשמור אותו בצד, וכו'.



סיכום


צללנו ליכולות ה DSL של קוטלין. מקווה שיצאתם מזה בשלום :)

אני רוצה לסיים בדיון קטן ב StackOverflow שנתקלתי בו, המייצג לדעתי היטב את הנושא:

>> בחור אחד שאל אם יש בקוטלין משהו דומה ל (rand(0..n של רובי, ביטוי המחזיר מספר רנדומלי מהטווח.
>> פתרון יפה שהציעו לו התבסס על extension function למחלקת ה CustomRange של קוטלין:


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

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

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


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



2017-08-13

קוטלין (Kotlin) למפתחי ג'אווה ותיקים - חלק ד': עוד על מחלקות, אובייקטים, ועוד...

פוסט זה הוא המשך של:
קוטלין (Kotlin) למפתחי ג'אווה ותיקים - חלק א': הבסיס
קוטלין (Kotlin) למפתחי ג'אווה ותיקים - חלק ב': פונקציות
קוטלין (Kotlin) למפתחי ג'אווה ותיקים - חלק ג': מחלקות

בואו נתחיל!


היררכיית הטיפוסים של קוטלין


בקוטלין, האב הקדמון של כל האובייקטים הוא Any - המקבילה של Object בשפת ג'אווה.

כך נראה אובייקט ה Any (השמטתי את ה comments):


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

המחלקה Any מכילה גם כמה extension functions (החשובות שבהן: apply, let, run, also) - המוגדרות בקבצים אחרים. נדון בקונספט ה extension function ובמתודות הללו ספציפית - בהמשך הסדרה.

האם Any הוא באמת האב הקדמון של כל המחלקות בקוטלין?
לקוטלין יש את מערכת ה Nullable, שבעצם אומרת ש:

Any? = Any || null

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

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


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

הזכרנו כבר שבקוטלין אין פרימיטיביים, ולכן כל ה wrappers (כמו Int) - יורשים בעצם מ Any.

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

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

השימוש ב Nothing עוזר לסמן לקופיילר מקרים ש"הקומפיילר לא צריך לדאוג מהם". למשל, המימוש הבא של EmptyList (זהו ה pattern של NullObject - למי שמזהה):

מקור

הורשה בקוטלין


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

  1. עלי להצהיר על המחלקה open, אחרת תהיה לי שגיאת קומפליציה שתצביע על המחלקה SpecialPerson שיורשת אותה. מחלקות הן final בקוטלין, כברירת מחדל. זו גישה הגנתית המספקת פחות הפתעות מהורשה לא צפויה.
  2. כנ"ל לגבי פונקציה: כל הפונקציות הן final כברירת מחדל - ויש "לאפשר" לרשת אותן במפורש.
  3. חובה להגדיר override בפונקציה שדורסת מימוש של מחלקת-האב, בניגוד לאנוטציה Override@ בג'אווה - שהיא רשות. 
  4. התחביר של הורשה הוא : - כמו ב #C. סוגריים נדרשים כדי לדעת אם להפעיל את בנאי-ברירת-המחדל של מחלקת האב - או בנאי אחר.

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

  1. הגדרתי את המתודה a כ final במחלקה SpecialPerson. לולא ההגדרה - הגדרת ה "open" מהמחלקה Person - הייתה ממשיכה הלאה במורד ההיררכיה.
  2. ...ולכן - יש לי שגיאת קומפליציה בבואי לדרוס אותה.


מחלקות חתומות (Sealed Classes)


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

  1. אני מגדיר את המחלקה InsuranceResult כ sealed (במקום Open). זה יתיר רק למחלקות שהוגדרו באותו הקובץ (private scope) - לרשת ממנה.
  2. הנה יצרתי 2 מחלקות פשוטות. העימוד בא להדגיש את הקשר.
  3. שימוש נפוץ הוא בכדי להחזיר סט סגור של ערכים. למשל: פעולה של אישור ביטוח שיכולה להסתיים בהצלחה (תשובה מסוג אחד - Approved) או בכישלון (תשובה מסוג אחר - Denied).
    1. המחלקות Denied, Approved, ו InsuranceResult - הן public, וניתן להשתמש בהן מכל מקום.
  4. הנה הקוד שמקבל את התשובה, גם הוא - פשוט ואלגנטי.



מחלקות מופשטות (abstract), וממשקים (interfaces)


בקוטלין יש מחלקות מופשטות (abstract):

  1. עצם ההגדרה של מחלקה כ abstract אומרת ש:
    1. המחלקה יכולה להכיל members מופשטים (abstract).
    2. לא ניתן ליצור instances ממנה.
  2. הנה פונקציה מופשטת. פונקציה מופשטת היא "פתוחה" (open) בהגדרה.
  3. אפשר גם להגדיר פונקציות קונקרטיות - עם מימוש. הם יהיו "סגורות" כברירת מחדל.
  4. כשאני דורס פונקציה מופשטת, עדיין עלי להצהיר על דריסה בעזרת override.
  5. יש לי שגיאת קומפילציה, מכיוון וניסיתי לרשת פונקציה ממחלקה מופשטת, בלי המילה override. מוסיפים override - ויש שגיאה נוספת. מה הפעם?
    1. כברירת מחדל פונקציות (ומחלקות) הן final. עלי לשנות את ה פונקציה collect ב InventoryItem להיות open - ורק אז הכל יסתדר.

ממשקים בקוטלין הם דיי דומים לג'אווה - עם כמה הבדלים קטנים.

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

  1. הנה הגדרה של ממשק פשוט: יש בו פונקציה אחת מופשטת (ללא מימוש), ואחת קונקרטית - עם מימוש.
  2. בממשקים של קוטלין ניתן להגדיר תכונות, אבל ללא state (חייבים להגדיר getter, ולא יהיה  backing field מאחורי התכונה). 
    1. שימוש אפשרי לתכונות על ממשק - היא כחלופה לקבועים על הממשק - שאין בקוטלין.
  3. הנה אני יוצר אובייקט שיורש מ Person ומממש את הממשקים Happy ו Shiny. סדר ההגדרה של הממשקים / מחלקת אב - לא משנה.
  4. אני מחויב לדרוס את המתודות המופשטות של הממשקים, כמובן - ולספק להן מימוש קונקרטי.
  5. מה קורה כאשר לכמה ממשקים שירשתי מהם, יש פונקציה קונקרטית עם חתימה זהה (בדוגמה שלנו: reflect)? כיצד לא נגררים לבעיות של הורשה מרובה?
    הפתרון של קוטלין אלגנטי: הקומפיילר מחייב אותי לממש מחדש את הפונקציה.
    1. שימו לב שאם החתימה היא שונה (פרמטרים שונים) - אז אין בעיה, ואני לא אחויב לממש מחדש.
  6. אם אני רוצה לפנות למימוש קונקרטי - אני פשוט קורא ל <super.<function name.
    שנייה! יש פה בעיה: הקומפיילר לא יודע איזה מימוש של reflect אני רוצה לקבל: של Shiny או של Happy?
    1. הפתרון הוא לבאר לקומפיילר מה אני רוצה, בעזרת התחביר הבא: (super<Happy>.reflect(s 
      כשאני משתמש בתחביר הזה - הקומפליציה תקינה, וקריאה ל ()reflect של S.H.Person - תפעיל את המימוש הקונקרטי של Happy.

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

אפשר לאפיין ארבעה הבדלים בין מחלקות מופשטות לממשקים:
  1. במחלקה מופשטת כל ה members הם final כברירת מחדל (כמו כל מחלקה) - בממשק הם open, ולא ניתן להגדיר אותם כ final.
  2. בממשק לא ניתן להגדיר members כ internal. ורק פונקציות קונקרטיות ניתן להגדיר כ private. בקטנה.
  3. מחלקה יכולה לרשת ממשקים רבים - אך רק מחלקה מופשטת אחת - זה כנראה ההבדל הכי חשוב.
  4. זה מעט מורכב: ממשק לא יכול להחזיק state, אחרת עלולים להיווצר קונפליקטים במימוש-מרובה.
    לכן, השפה מציבה כמה מגבלות על תכונות (properties) שהוגדרו בממשקים:
  1. בממשק אני יכול להגדיר val או var:
    1. val - ניתן להגדיר לו getter בלבד, או להשאיר את התכונה מופשטת (abstract).
    2. var - התכונה תמיד תהיה מופשטת. ניסיון להוסיף getter יגרור לשגיאת קומפילציה.
  2. מכיוון שהתכונות של הממשק Koo הן מופשטות - המחלקה המממשת חייבת לממש את התכונות הללו: x ו y (להלן override), ואז עלי לנקוט באחת מהגישות הבאות:
      1. אני יכול להציב בתכונות ערך התחלתי (מה שאי אפשר לעשות בממשק)
      2. אני יכול לממש getter/setter בעצמי.
        1. הערה: val הוא readonly - ולכן אין צורך ב setter.
      3. אני יכול לדרוס את התכונות ב primary constructor. הערכים שהוגדרו שם "יחביאו" את אלו שהוגדרו על הממשק.

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


מחלקות מקוננות (Nested Classes)


בקוטלין יש 2 סוגים של מחלקות מקוננות:

  1. Minion היא מחלקה מקוננת של Father, סתם כך.
    כברירת מחדל מחלקה מקוננת היא "סטאטית" כלמר - מחלקה עצמאית לכל דבר שרק חיה ב namespace של המחלקה שעוטפת אותה.
    1. יוצרים אותה בנפרד.
    2. היא לא יכולה לגשת לתכונות / פונקציות של מחלקת האב.
  2. בצורה השנייה, משתמשים במילה השמורה inner, בכדי לחבר את המחלקות ברמת המופעים (instances)
    1. לא ניתן ליצור מחלקה פנימית ללא החיצונית. ביצירת מופע של המחלקה החיצונית - נוצר גם מופע, מקושר, של המחלקה הפנימית.
    2. אם יש התנגשות בשמות, ניתן להשתמש ב qualified this" expression" - להגיע למחלקת האב. דומה מאוד ל OuterClass.this בג'אווה.
      1. ניתן גם להשתמש ב qualified super, בתחביר ()super@Father.foo - בכדי לגשת לפונקציה של המחלקה ממנה האובייקט החיצוני יורש.


מה קרה ל static ובן-אל?


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

  1. בעזרת המילה השמורה object, אנחנו בעצם מגדירים מחלקה - ומייד יוצרים לה מופע.
    1. אובייקט הוא מופע יחיד (singleton). השימוש הנפוץ בו הוא ליצירת Factory או אובייקט שמכיל איברים סטטיים - המשותפים לכולם.
    2. ניתן להגדיר על האובייקט תכונות, ופונקציות - אבל לא בנאים. הרי: לא יוצרים אותו. המופע נוצר בעצם ההגדרה.
    3. ניתן לרשת ממחלקה אחרת / לממש ממשקים.
  2. אם היינו רוצים להגדיר קבוע בג'אווה היינו משתמשים ב static final. בקוטלין קיימת במילה השמורה const שמצביעה לקומפיילר שמדובר בערך שידוע בזמן קומפילציה. השימוש ב const היא הצהרה שזהו ערך סטטי שלא הולך להשתנות. המשמעות:
    1. אי אפשר להציב תשובה מפונקציה, קרי ()const val x = foo - זו שגיאת קומפילציה.
    2. אי אפשר להוסיף getter - הרי getter יוכל "לשנות את הערך, ע"י החזרה של ערך אחר", ולעולם בעתיד לא יהיה ניתן להוסיף getter. זו אולי התכונה בעלת הסמנטיקה העמוקה ביותר.
    3. אפשר לאתחל את התכונה רק ערכים פרימיטיביים (מספרים, מחרוזות), ולא אובייקטים - אחרת, ייתכן אי אפשר להבטיח שכלום לא ישתנה.
    4. בפועל: מאחורי const לא יהיה backing field.

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

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

  1. לצורך הדוגמה יצרתי אובייקט מקונן בתוך המחלקה. 
    1. זו צורת עבודה לגיטימית. תחביר-ההפעלה הוא קצת יותר מסורבל, כי יש לציין את שם האובייקט.
  2. כאשר אני מגדיר companion object, אני יכול לפנות לפונקציות שלו, ישירות תחת ה namespace של המחלקה. ל companion object:
    1. אין צורך להגדיר לאובייקט שם.
    2. ניתן להגדיר רק companion object יחיד בכל מחלקה.
    3. ה companion object ייווצר בזמן שטוענים את קוד המחלקה - מה שמקביל את הפונקציות שלו ל static methods בג'אווה.
  3. ה annotation של JvmStatic@ היא רשות, והיא תגרום ל bytecode שנוצר לגרום לג'אווה להתנהג עם ה companion object בצורה דומה לאופן הטיפול בקוטלין.
    1. ללא ה annotation יש לקרוא בג'אווה: ()Log.Companion.createLogger
    2. עם ה annotation יש לקרוא בג'אווה: ()Log.createLogger
  4. אם המחלקה עושה shadowing למשתנה / פונקציה של ה companion object, אני יכול בצורה מפורשת לגשת ל member של ה companion object בעזרת השם Companion.



שונות


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

late init

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

  1. הפתרון ה"פשוט" הוא להציב ערך null בשדה - עד האתחול ה"אמיתי".
    1. בקוטלין זה דיי מעצבן, כי אז עלי להפוך את כל הטיפול באותו משתנה ל nullable - התעסקות מיותרת.
  2. הפתרון: להוסיף modifier בשם lateinit, המורה לקומפיילר: "אחי, עלי! המשתנה הזה יאותחל לפני שיקראו לו". השימוש ב lateinit מאפשר קוד נקי יותר, ללא טיפול ב nullability.
    1. מצד שני: אם טעינו (והטענו את הקומפיילר) - תיזרק שגיאת ...UninitilizedProperty.
      שם השגיאה, מכוון למהות הבעיה, יותר טוב מאשר לקבל סתם Kotlin)NullPointerException).
  3. כאשר מגדירים lateinit, השדה של התכונה (במקרה שלנו: repository2) ייחשף לקוד הג'אווה. זוהי החלטה תכנונית של מקסום התאימות לג'אווה. 
    1. אפשר למנוע את חשיפת השדה ע"י ה annotation האופציונלי: field:JvmSynthetic@

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




גישה לאובייקט ה Class

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

ספריות שונות משתמשות ביכולת הזו, למשל: JUnit:

@RunWith(RobolectricTestRunner.class)

בקוטלין, ניתן לגשת לאובייקט ה reflection המתאר את המחלקה בעזרת הקריאה object::class - זהו אובייקט של ספריית ה runtime של קוטלין מסוג <*>KClass (על הכוכבית - בהמשך הסדרה).
הוא מכיל מתודות ותכונות reflection של קוטלין, למשל companionObjectInstance - המחזירה מצביע ל companion object, אם קיים.

רוצים לקבל את אובייקט הג'אווה המתאר את המחלקה שלנו (אובייקט ה Class, שהוא בעל מבנה שונה מאובייקט ה KClass)? - קראו ב object::class.java.

ברוב הפעמים דווקא נדרש לאובייקט-המטא של קוטלין. למשל:

@RunWith(RobolectricTestRunner::class)

זה תלוי מה הספריה עושה איתו. זה עניין של ניסוי וטעייה.




סיכום


בפוסט זה כיסינו את רוב הנושאים שנותרו לגבי אובייקטים, הורשה, ממשקים, וכו'.

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


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



2017-08-10

על InsurTech - הדומיין, והבאזז

טוב, אפתח בעדכון אישי קצר:

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

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

עכשיו גם הגיע הרגע להתעמק בדומיין, ולנסות להבין באיזה ביזנס מדובר. לקח לי קצת זמן להגיע לשלב הזה, כנראה בגלל ש"ביטוח" לא נשמע הדבר הכי מרגש בעולם (... גם "מוניות" לא נשמע - אבל זה שוק סוער ומסעיר). החברה גייסה סכומי כסף יוצאים מן הכלל (13 מ' סיד, 35 מ' סבב A תוך שנה) - מה שנסך בי ביטחון שלא מדובר ב"חלטורה". היזמים גם מגיעים מתחום דומה (מכרו את Check, אפליקציה לניהול פיננסי, ב 360 מיליון) - יתרון משמעותי מאוד. הם גם שלושתם צמחו מעולם התוכנה - מה שכנראה יאפשר להוציא מה R&D את המקסימום.

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

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

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

נתחיל.



סוגים שונים של ביטוח


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

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


כן, יש שם הרבה כסף. מקור: WordStream

ומה עם עולם הביטוח? לכאורה זה עשוי להישמע לנו שולי, אך יש תחומים שונים ודיי נפרדים זה מזה בעולם הביטוח:
  • ביטוח בריאות (health) - עוזר בכיסוי הוצאות רפואיות בעת הצורך.
    • מדינות רווחה מספקות ביטוח בריאות ממלכתי, שמאורגן על ידי המדינה ומוצע לכל האזרחים, ויש ביטוח בריאות המסופק ע"י חברות הביטוח.
    • בישראל, למשל, יש 3 מסגרות של ביטח בריאות:
      • ביטוח ממלכתי - דמי הביטוח נגבים ע"י מיסים (כחלק מתשלום הביטוח הלאומי) וכדמי חברות בקופת-חולים, והכיסוי אחיד לכל התושבים. סל הבריאות (נקרא בטעות גם "סל התרופות") הוא חלק מהביטוח הממלכתי.
      • שירותי בריאות נוספים - המוצעים ע"י קופות החולים, למשל "מכבי זהב".
      • פוליסות ביטוח פרטיות ("ביטוח משלים") - המוצעות ע"י חברות הביטוח, למשל: ביטוח סיעודי.
    • זה תחום אחד. הנה ב Udemy קיימים 1 2 3 4 קורסים שונים - ספציפית על תחום ביטוח הבריאות.
  • ביטוח חיים (life) - ביטוח המאפשר תשלום חד פעמי גבוה, או הכנסה קבועה - בעת פטירת המבוטח. הביטוח בעצם מגן על המשפחה מאבדן הכנסה.
    • וריאציה חשובה היא ביטוח אבדן כושר עבודה (annuity) -  המפצה את המבוטח במידה ואיבד את חוסר היכולת להמשיך ולעבוד (בשל נכות, למשל).
    • "ביטוח מנהלים" בישראל - הוא בעצם ביטוח חיים. פנסיה, היא סוג של ביטוח annuity - המנוהל בד"כ ע"י המדינה.
  • ביטוח רכוש (property) - דירה היא הנכס בעל הערך הכספי הגבוה ביותר של משפחה ממוצעת, ולכן יש ערך רב להתמודדות עם מצב שנפגעה: שריפה, נזקי מזג-אוויר, נזילות, או פגעים אחרים.
    • תת-תחום מרכזי הוא ביטוח תכולת דירה (content) - ביטוח על הריהוט ורכוש, לרוב בעקבות שריפה או פריצה.
    • גם שדה חקלאי, מלאי של חנות / מפעל, ספינות מטוסים, ועוד - מבוטחים כ property.
    • תת-סעיף אחר הוא ביטוח מוצרים (product) - הרחבת אחריות היצרן לתקופה נוספת, למשל למכונת כביסה או מקרר.
  •  ביטוח בפני תאונות/אסונות (casualty) - ביטוח הרכוש עצמו, (וגם ביטוחים אחרים) - לרוב לא כוללים כיסוי למקרי קיצון. זה סיכון אחר, עם משמעות אחרת. למשל: ביטוח רכוש פעמים רבות לא מכסה מקרה של גניבה. ההשלמה הזו (שמופיעה כאופציה בפוליסה) - נחשבת ביטוח casualty. לרוב מתייחסים לביטוחים הללו ביחד, כ property & casualty -למרות שמבחינת תהליך הביטוח - ההבחנה היא חשובה.
    • ישנם שורה של ביטוחי casualty למקרים נדירים פחות ויותר: ביטוח בפני פריצה ופשעים אחרים, ביטוח בפני אירועי טרור (בביטוחי נכסים לרוב יהיה סעיף שמחריג אירועי טרור), ביטוח בפני חטיפה, ביטוח בפני חטיפה ע"י חייזרים (כן, כן), וכו'.
    • ביטוח שנהיה פופולרי בתחום הוא ביטוח כנגד התקפות סייבר. לא הצלחת למנוע? לפחות תתגונן ביטוחית בפני הנזק.
  • ביטוח רכב (auto) - העוזר בכיסוי עלויות רפואיות, עלויות לרכוש (תיקון הרכב / רכב חדש), ו Liability - תשלום לצד אחד - במידה והוא נפגע (רפואית / רכוש) בגללנו. 
    • בגלל שחלקים מהביטוח ("ביטוח חובה", בישראל), מחויבים ע"פ חוק - השוק הזה גדול ומשמעותי.
    • בעצם מדובר בשורה של סוגי ביטוחים (בריאות, רכוש, liability) - שמאחדים בשל גודל השוק והדרישה הרגולטורית.
אלו הן ה"גורילות" של עולם הביטוח - היכן שרוב הכסף הולך, מתוך מחזור שנתי של 4.8 טריליון ( 4,800,000,000,000 $) דולר בשנה ברחבי העולם. בארה"ב, ביטוח מהווה כ 7% מהתל"ג - חלק משמעותי ביותר!
רשת Starbucks, למשל, מוציאה יותר על ביטוח - מאשר על חומרי גלם לקפה.


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




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


ככלל, שוק הביטוח הוא מבוזר למדי:
  • תחומים שונים, כמו ביטוח חיים וביטוח רכבים - עליהם דיברנו הרגע.
  • לכל מדינה יש רגולציות רבות ושונות לתחום הביטוח, הדורשים התמחות עמוקה - ועל כן יש מעט חברות "גלובליות".
    • גם כאשר משתמשים באותו brand (למשל: AIG או AXA) - במדינות שונות אלו לרוב יהיו חברות שונות.
  • בשום שוק של ביטוח אין כמעט שחקן שגדול מ 10% מהשוק. יש ריבוי שחקנים, וכבר לאורך זמן.

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


מכאן זה נשמע פשוט: תוכנה שמשרתת חברות ביטוח - מעכשיו נקראת "InsurTech", והנה יש לנו באזז חדש!
Sapiens, למשל, החברה הישראלית שמפתחת תוכנה לחברות ביטוח מאז 1982 - היא בוודאי חברת InsurTech. נראה שהכל ברור!

בפועל:

הכוונה ב InsurTech היא לחברות שהולכות לעשות שינוי משמעותי באופן שבו תחום הביטוח עובד. לרוב מדובר על חברות startup.

את חברות ה InsurTech מחלקים ל-2 קטגוריות עיקריות (ולא חד-משמעיות):
  • חברות שמנסות להחליף את חברות הביטוח שפועלות היום. למשל:
    • Lemonde [רכוש, היבטים מסוימים של P2P] - חברה ישראלית צעירה בתחום ביטוח הרכוש, בעלת פרופיל תקשורתי גבוה. Lemonade שכרו את פרופ' דן אריאלי כיועץ. במודל של למונייד הלקוחות מאוגדים כ"קבוצות עניין" ותורמים את עודפי הביטוח שלא התממש לצדקה - מה שאמור (בתאוריה) לצמצם את ניגוד האינטרסים המזיק בין חברת הביטוח למבוטח, וגם לצמצם הונאות.
    • Zenefits [בריאות עובדים] - מספקים בחינם תוכנת HR לארגונים, על מנת ליהנות מעמלת תיווך בביטוח בריאות לעובדי החברה שנעשה דרך התוכנה - דבר שנמצא בשטח האפור בתחום הרגולציה, והם כבר זכו לכמה תביעות.
      החברה קיימת כ-4 שנים בלבד, אבל גייסה כבר יותר מחצי מיליארד דולר.
    • FriendsInsurance [אישי / רכוש, P2P] הגרמנית, מציעה מודל P2P - בו קבוצת חברים שזקוקה לביטוח בתחום דומה, יוצרת בינה לבין עצמה pool של הון, שישמש לפיצוי אפשרי במידה ואחד החברים נפגע. חברת הביטוח מספקת ביטוח-משנה ל pool (נניח: כל החברים היו מעורבים ביחד בתאונת שרשרת בטיול לכנרת). בכלל, "pools משותפים של הון" - הם באזז בתוך עולם ה insurTech.
    • Cover [רכוש] - חברה שמספת ממשק מאוד חדשני לביטוח פריטים (תכשיטים, אלקטרוניקה, וכו'): מצלמים באפליקציית מובייל את הפריט, מקבלים הודעה מאוחר יותר על הצעה לביטוח, ומאשרים באפליקציה. תמונה (שכוללת את האלמנטים הנכונים) - שווה אלף מילים.
  • חברות שמנסות לשפר תהליכים של חברות הביטוח שפועלות היום. למשל:
    • Cape Analytics [ביטוח רכוש, שיפור חיתום] - משתמשת בתצלומי אוויר + computer vision בכדי לזהות פגעים בנכס מבוטח, ומשווה צילומים לאורך זמן על מנת לזהות שינויים בנכס.
מקור: Cape Analytics
    • SocialIntel.com [שיפור חיתום / ביטוח רכב] - חברות הביטוח היום, בנוסף לפרטים שממלא המשתמש, קונות גם מידע על Credit History, ו driving history של הלקוח בכדי להעריך את הסיכון - מידע לא זול. SocialIntel מציעה אלטרנטיבה: היא "כורה" נתונים על המשתמש מתוך הרשתות החברתיות, מזקקת את התובנות השימושיות עבור חברות הביטוח - ומוכרת אותו בהרבה יותר זול. כמו כן היא תמשיך לאסוף מידע על המשתמש גם לקראת תביעה ו/או חידוש הפוליסה 😕.
    • עוד חברה ששווה להזכיר היא Nexar הישראלית [ביטוח רכב / Telemetrics], שמספקת אפליקציה שעוזרת להתריע בפני סכנות בכביש ("כמו מובילאיי, ללא חומרה ייעודית"). Nexar היא לא חברת InsurTech ייעודית, אלא זהו פן אחד במוצר שלה: המידע על אופן הנהיגה של המשתמש יכול להיות מועבר לחברת הביטוח על מנת לקבל הנחה בביטוח - אם הנתונים מראים אכן שהמשתמש נוהג בזהירות. חברות דומות הן Greenroad ו lytx, הקצת יותר ותיקות. 
    • חברות שונות מנסות לשפר את תהליכי ה Big Data והתהליכים הפנימיים של חברות הביטוח - ששניהם נחשבים מיושנים ומסורבלים בצורה מהותית, אולם לא מצאתי חברות מעניינות במיוחד ששווה להזכיר.


שרשרת המזון בעולם הביטוח, וחברות ה InsurTech


חוץ מה vertical הביטוחי, חברות ביטוח פועלות בשלבים שונים של התהליך הביטוחי. נחלק את תהליך הביטוח ל 3 שלבים / אזורי מומחיות:
  • הפצה - למכור את הביטוח. מלבד ביטוח בריאות או רכב, שיש רגולציה שמחייבת אנשים לקנות ביטוח שכזה (כמה נוח!), ביטוח הוא סוג מוצר ש"מוכרים", ולא כ"כ "קונים". לבנאדם לא "מתחשק" בוקר יום אחד לרכוש ביטוח לתכולת דירה (בניגוד, אולי, לסמארטפון חדש).
  • חיתום (Underwriting) - מישהו צריך להתמחות בתחום המסוים, ולשערך את הסיכון.
    • כמה מסוכן להוביל פסנתר כנף עתיק בכבישים של דרום פינסלבניה? לחברות הביטוח הגדולות יש מאות, ואלפי אנסליסטים - אבל הם מתמקדים בשווקי הביטוח העיקריים. את שאר שערוך הסיכונים - עושים שותפים של חברות הביטוח, כל אחד - המתמחה בתחומו [א].
    • מקור המינוח Underwriting, אגב, הוא מהביטוח הימי. באותם ימים היה מסמך שתיאר את פרטי הסכם הביטוח והסיכונים הנלקחים, והמבוטח היה כותב את שמו המלא (writing) באזור שנשמר לכך תחתית המסמך (under).
  • ניהול נכסים (Portfolio Management) - הפער בין הזמן בו הלקוח הממוצע משלם עבור הביטוח, ועד הזמן שהוא מגיש תביעה (claim) ומקבל חזרה את הכסף, הוא זמן לא מבוטל שבו הכסף "יושב" בידי חברת הביטוח.
    • חברות הביטוח, אם כן, מחזיקות סכומים אדירים של כסף - חלקו לזמן ארוך מאוד (למשל: ביטוח חיים).
    • את הכסף הזה חברות הביטוח משקיעות פיננסית, ועבור חלק מחברות הביטוח - הרווח מהשקעות הוא יותר משמעותי מהרווח שמושג מפרמיית הביטוח (premium).
    • הרגולציה מחייבת את חברות הביטוח לשמור את סכומי כסף מסוימים נזילים בכל עת: אם יש "spike" של תביעות - על חברת הביטוח להיות מסוגלת לשלם אותן.

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


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

הנה סוגי ה"פוזיציות" השונות בתחום הביטוח ל insurTech startups, והמשמעות של כל פוזיציה:
  • Lead Generator (בקיצור: LeadGen) הוא שחקו שעוזר לבצע מכירות, או לפחות להשיג Leads. הוא לוקח עמלה מכל עסקה, מה שמהווה עבורו מעט מאוד סיכון.
    • Wobi הישראלית היא דוגמה טובה לכך: היא מאפשרת השוואות חינם בין ביטוחים מסוגים שונים. העמדה הזו מאפשרת לה למכור Leads לחברות, או לגזור עמלה מכל עסקה שנסגרה דרכה (אני לא יודע מה המודל העסקי שלהם).
    • Lead Generators טובים יותר הם אלו שיודעים לעשות סינון ראשוני ל Leads ולהעביר לחברות הביטוח את ה Leads המבטיחים. סתם Leads - זו לא בעיה לייצר, וחברת הביטוח לא רוצה להשקיע זמן ב Leads חלשים.
    • Axiom, למשל, קונה Leads, מאמתת אותם - ומוכרת אותם הלאה. עושה סוג של qualifications על ה Leads ומוסיפה ערך בשרשרת.
    • שחקנים במגזר הזה צריכים לשים לב לשורה של חוקים להגנת הצרכן / פרטיות - שעליהם לכבד.
  • "סוכני הביטוח" (נקראים גם Producers) מתחלקים לכמה סוגים, אבל בעיקר לAgents ו Brokers.
    • סוכן עצמאי (Independent Agent) - המייצג כמה חברות ביטוח (carriers) ומוכר מוצרים שונים שלהן. מוצר הוא פוליסת ביטוח עם תנאים מסוימים, וחברת הביטוח מאשרת רשימה של מוצרים שהיא מתירה לסוכן למכור.
    • ברוקר (Broker) - הוא דומה מאוד לסוכן עצמאי, אך חוקית הוא משרת את הצד הקונה את הביטוח. אין לו הסדר עם חברות ביטוח (הוא לא "מאושר" על ידן), והוא מחפש ללקוח שלו מוצר מתאים.
    • Captive Agents - הם סוכנים המחויבים למבטח אחד, ומוכרים רק מוצרים שלו. המודל העסקי שלהם מתבסס על מומחיות מיוחדת בתחום (בד"כ - נישה).
    • Wholesale broker - הם מתווכי ביניים המהווים ערוץ מכירות לא-ישיר של חברות הביטוח מול סוכני ביטוח / ברוקרים רגילים, שאין להם "הסמכה" למכור מוצרים של חברת הביטוח. מדוע להוסיף עוד שכבה, שגוזרת חלק מהרווח - אתם בוודאי שואלים? בגלל שעולם הביטוח הוא מבוזר וכולל נישות רבות - בהן קשה ואולי אף לא יעיל לחברת הביטוח להתמחות.
    • Sub Producer - היא חברה שעושה שימוש במינוי שניתן לסוכן ביטוח, על מנת להיות מוכר-משנה של אותו סוכן ביטוח.
    • שוני מהותי בין LeadGens ו סוכנים/ברוקרים הוא שסוכנים וברוקרים בד"כ יכולים לבצע bind לפוליסה: לספק ביטוח זמני (binder) למבוטח, עד אשר החיתום אצל חברת הביטוח יסתיים (מה שיכול לארוך גם שבוע-שבועיים)
    • סוכן ביטוח זקוק להסמכה ע"י חברת הביטוח, וגם ע"פ רגולציה במדינה - שלעתים כוללת מבחן עיוני שהעובדים צריכים לעבור. בארה"ב יש 50 מדינות - כל אחת עם הרגולציה שלה, שגם שונה מתחום לתחום (חיים, בריאות, רכוש, וכו'). הרגולציה הזו היא חסם כניסה משמעותי לסטארט אפים בתחום הביטוח.
      • שווה להזכיר שיש יוזמה לאחד את הרגולציה ברמה הפדרלית בארה"ב - רגולציה אחת לכל המדינות.
  • Managing General Agent (בקיצור MGA) - הוא סוג מיוחד של agent/broker שלו יש גם יכולת חיתום (Underwriting), ולהתמודד עם תביעות (claims).
    • MGAs גם יכולים למנות סוכנים (producers / sub-producers) ממש כמו carriers.
    • MGAs במקור קיימים כתחום התמחות בנישה מסוימת, שחברת הביטוח הגדולה אינה מכסה.
    • המודל הכלכלי של MGAs הוא עמלות, בצד שותפות הרווח/הפסד עם חברת הביטוח של החיתום שעשו.
    • MGA, בדומה ל carrier, זקוק לרישיון רגולטורי לפעילות - ע"פ חוק.
    • סוג של MGA הוא "quasi-carrier" שלוקח בתוכנית fronting מול חברת ביטוח (להלן ה Fronting Partner).
      • תוכנית ה fronting מאפשרת ל MGA להשתמש ברישיון של חברת הביטוח וההון שברשותה (כחלק מדרישות הרגולציה), בתמורה לנתח ברווחים.
  • חברת ביטוח (Carrier, נקרא גם "provider") - זה "הדג השמן" בעולם הביטוח. הוא עשוי להתפרס על תחומים שונים (ביחידות שונות), ועל חלקים שונים בשרשרת המזון (חיתום, bind, טיפול בתביעות, מכירות, השקעות פיננסיות, וכו') - אם כי לרוב חברות הביטוח עובדות עם ריבוי שותפים, בכדי לכסות תחומי מומחיות שונים.
    • חברת ביטוח יכולה ללבוש אחת מ-2 צורות רגולטוריות:
      • admitted - חברה בעלת רישיון בכל מדינה שהיא פועלת בה, למשל 50 מדינות בארה"ב.
      • non-admitted - מודל בו חברה יכולה לפעול במדינה תחת רגולציה פחות מחמירה, אך גם חוסר הגנה מצד המדינה. כשיש פחות רגולציה, הפרמיות לרוב יהיו זולות יותר, אך יש גם יותר סיכון למבוטח, שמא החברה תיקלע לקשיים לא-צפויים ולא תזכה להגנת המדינה.
    • captive - היא חברת ביטוח, שהיא בעצם חברת בת של חברה שאינה עוסקת בביטוח ומספקת ביטוח לחברת האם (לרוב: חברות ענק שמשתלם להן להקים כזו אופרציה). ה captive insurer לעתים יכול לקום במדינה עם רגולציה עדיפה (כמו אירלנד, לוקסמבורג, ברמודה, מלטה) - מה שמספק בהקמה, ובתשלום מסים. הנה מקור שמסביר טוב יותר את הנושא.
    • חברות הביטוח מרוויחות לא פחות מהשקעות, מאשר ממכירת פרמיות - ועל כן זהו עיסוק מרכזי אצלן.
      • בשנים האחרונות, כאשר הריבית ברחבי העולם היא אפסית - הרווחים מהשקעות פחתו, מה שדוחף את חברות הביטוח לחפש רווחים וצמיחה במקומות אחרים, למשל - בשותפות עם חברות startup.

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

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

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

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


נתוני השקעה ב startups בתחום ה insurtech. מקור: דו"ח על תעשיית ה InsurTech של גיקטיים, 2017
* באמצע 2015 היו 2 השקעות-ענק בתחום: כמיליארד דולר ל ZhongAn הסינית, וחצי מיליארד דולר ל Zenefits האמריקאית.


איך אפשר לדעת ש InsurTech הוא לא "באזז חסר משמעות"?


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

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

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

אמנם ה Obamacare יצר צמיחה גדולה בביטוח הרפואי בארה"ב, אולם בסה"כ הלחצים על חברות הביטוח - גוברים:
  • הריבית בעולם בשפל --> הרווחים מהשקעות פוחתים (והמשקיעים לא אוהבים את זה).
  • חלק מסוגי הביטוחים נמצאים ברגרסיה: בשנות השישים, כ 59% מאזרחי ארה"ב החזיקו בביטוח חיים. כיום - רק 36% מחזיקים. לא נראה שהצורך נעלם, אלא שהתעשייה לא הסתגלה לשינויים.
  • חלק גדול מפרמיית הביטוח "הולך" על תחזוקת מנגנונים מסורבלים והונאות. יש הרבה פוטנציאל התייעלות באזורים הללו, בעזרת טכנולוגיות-מידע עַכְשְׁוִיּוּת.
  • לחברות הביטוח יש קושי גדול מאוד לגייס כשרונות (talent). חבר'ה צעירים ומוכשרים - לא נוהרים לחברות הביטוח המסורתיות.
חברות הביטוח הן גדולות, מסורבלות, ומתמחות ברגולציה ובירוקרטיה - קשה להן מאוד לחדש.
למשל: רוב ביטוח הרכוש עדיין מתבצעים דרך סוכן, ובשיחת טלפון. תעשיית ביטוח הרכב היא חריגה, והיא הוכיחה שאפשר למכור ביטוח בצורה ישירה, ו Online - תוך כדי שיפור שביעות הרצון של הלקוחות וייעול תהליכים פנימיים.

התעשייה זקוקה לעזרה.

האמון בין חברת הביטוח והמבוטח - היא בעיית ליבה בתחום. מתוך ה Urban Dictionary.

מצד שני: ישנן הזדמנויות. טכנולוגיות חדשות, עשויות לפתוח הזדמנויות חדשות - רק אם ינצלו אותן נכון:
  • מובייל ואונליין הוא כבר הסטנדרט לתקשר עם לקוחות ברוב התעשיות. בביטוח, מלבד ביטוח הרכב - כמעט ואין נוכחות אונליין לחברות. זהו צד טכנולוגי שכבר עכשיו מוביל צמיחה גדולה בעולם הביטוח.
  • Big Data ו AI - מה יותר טבעי מ Machine Learning לבניית מודלים לחיתום וחיזוי סיכונים? חברות ביטוח רבות עדיין משלמות שכר גבוה לאנליסטים שעובדים באקסל.
    • כמויות ה Data הזמינות ושניתן לאסוף היום גדלו בצורה משמעותית - מה שאמור לאפשר בניית מודלים יעילים יותר להערכת סיכונים.
  • IoT ו Wearables - מאפשרות לחברות להציע למבוטח שיתוף מידע שגם יכול להעיד על מבוטח מועט סיכון לו אפשר להפחית את הפרמיה, וגם לגרום למבוטח להתנהגות "טובה" יותר - המפחית סיכון.
    • באופן מפתיע, אחוז גדול למדי (70-90%, תלוי במדינה) של משתמשים מצוטט במחקרים שיסכים לשתף נתונים - תמורת הנחה בפרמיית הביטוח.
  • Blockchain - היא טכנולוגיה בעלת פוטנציאל לשינויים עמוקים. למשל: להיות בסיס לתהליכי ביטוח שקופים ואמינים יותר.

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


חברה בשם Oscar, למשל, לביטוח בריאות בארה"ב החלה להציע חוויה נעימה ומודרנית לביטוח.

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


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


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

מה Oscar עשתה? בגדול - ביטוח כפי שכל בן מילניום היה מצפה שיהיה: פשוט, נוח, נגיש, ו informative ("מיידע").

האם השוק הזה כבר מוצה? ממש לא:



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


מה עם חברות הביטוח עצמן?


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

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

מתוך PwC Global InsuTech Report 2017

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

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

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


הנה שיקוף של הטכנולוגיות שחברות הביטוח רוצות להטמיע בשנה הקרובה:



SMB


Next Insurance פונה לשוק מאוד ספציפי: שוק העסקים הקטנים בארה"ב. ביטוח שנראה לי שהוא (אני עדיין לא יודע) בעיקר ביטוח Liability ו Property & Casualty - מה שגם נקרא Commercial Insurance.

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

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


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


השוק הפוטנציאלי של ביטוחים לעסקים קטנים בארה"ב הוא 100B $ בשנה - שוק לא קטן בכלל!

נשמע שיש על מה לדבר 😃

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


----

קישורים רלוונטיים נוספים

המכתב השנתי של וורן באפט (עיקר הפעילות של ברקשייר האת'וויי - הוא תחום הביטוח) למשקיעים - ממנו אפשר ללמוד לא מעט על מצב הביטוח בעולם, ובשפה פשוטה: http://www.berkshirehathaway.com/letters/letters.html

יסודות הביטוח: http://continuations.com/post/141655994885/insurance-fundamentals-contd-adverse-selection



----

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