מתודולוגיית ה DDD השפיעה על רבים בתעשייה, והיא זוכה בשנים האחרונות לפריחה מחודשת.
מחבר הספר, אריק אוונס (Eric Evans), לא היה דמות מוכרת ו/או מקושרת בעולם התוכנה.
הוא לא עבד בחברה גדולה או בעלת פרופיל תקשורתי מוכר.
בעצם – הוא היה דיי אלמוני.
עד היום, אין ערך בוויקיפדיה על שמו. פרופיל הלינק-אין שלו לא מזכיר דבר לפני 2003, ואפילו גוגל, אבוי לבושה, טועה – ומקשר את הספר שכתב לפרופסור כלשהו להיסטוריה – בשם דומה. בכדי למצוא פרטים על אריק הנכון פרטים – צריך להתאמץ!
![]() |
פאדיחה! |
כיצד ניתן להסביר השפעה גדולה שכזו על עולם התוכנה מאיש תוכנה אלמוני, ש”הגיע משום מקום”?
הפרט ההיסטורי שיכול להשלים חלק מהתמונה הוא הפוסט הבא, דף הפרופיל של אריק ב WikiWikiWeb, הוויקי הראשון בעולם – שהוקדש לרעיונות בהנדסת תוכנה:
את WikiWikiWeb תחזקו Kent Beck ו Ward Cunningham, וברגע שדמות מוכרת כמו Kent Beck התלהבה מהספר – הדלתות נפתחו, וכמעט כל עולם התוכנה שמע על הספר.
ב 2003, וקצת אחריה – הספר נחשב ליצירת מופת של הנדסת תוכנה.
אבל מכיוון שזהו ספר ארוך (560 עמודים), ושאת הרעיונות שבו לא קל לממש – העניין בו דעך. אפילו נאמר עליו שהוא מציג רעיונות נהדרים – שלא רבים סיפורי ההצלחה של היישום שלהם בפועל.
אריק עבד כיועץ מאז, והמשיך להסביר ולמכור את רעיונותיו. הוא לא הוציא ספרים נוספים – ולא הרבה בהופעות.
— fast forward —
בערך ב 2014, כשאנשים כמו Martin Fowler, ו James Lewis ניסו להסביר לעולם את רעיונות הארכיטקטורה של MSA – הם השתמשו במונחים כמו Bounded Context וחזרו להזכיר את DDD. רעיון משפיע אחר הוא הרעיון של Event Sourcing (המופיע בספר פשוט כ “Domain Events”) – שיש לו קשר חזק לבאזז אחר: CQRS.
אריק חזר להופיע בכנסים חשובים, ואפילו יש כמה כנסים חדשים שמוקדשים ל DDD (למשל: DDD Europe). במשך השנים יצאו כמה ספרים נוספים על DDD (אריק הוציא תקציר “reference” לספר המקורי) וניתן היום למצוא מקורות כמו DDD Weekly – שהחל את דרכו רק בשנה שעברה. כמות הכתבות ב Medium והדיונים ב Hacker News לגבי DDD (ע”פ תחושה אישית ולא מדויקת שלי) – והלכים וגדלים.
DDD חזר למרכז הבמה!
בפוסט אחד לא אוכל לספק עומק סביר למתודולוגיה שלמה – אבל אנסה להסביר מהו DDD, מתי הוא מתאים, ומה הרעיון (בגדול) מאחורי הגישה.
הנה מתחילים!
אז הנה זה לפניכם, רשימת ה Patterns שמציג הספר והקשרים ביניהם:
מה… אתם צריכים דקה בכדי לעכל את התרשים? … שעה?…….. יותר?!
לא לא.. – חכו. זה לא ילך ככה.
בואו נתחיל מהתחלה, ולא נסתבך. יותר מדי אנשים הסתבכו כבר עם DDD.
DDD מציג רעיונות רבים, אבל מה העיקר?
מהם 3-4 הרעיונות הכי חשובים שהבנה שלהם יכולה לתרום לשיפור מעשי במאמץ הקטן ביותר? (זו תמיד שאלה טובה…)
רואים בתרשים למעלה את ארבעת המעגלים הגדולים ביותר? – אלו הם גם הרעיונות החשובים ביותר במתודולוגית ה DDD.
אמנם שלושה מהם מכוסים בספר בשלב מאוחר (פרקים 14 ו 15 !!) – אולם אריק בעצמו מספר שזו הייתה טעות, שהוא לא נתן לרעיונות הללו את הדגש הנכון. שאם היה כותב את הספר מחדש, אלו ככל הנראה היו פרקים 2 ו 3.
בגדול אפשר לומר שמתודולוגית ה DDD עוסקת בשני אזורים:
- בניית מודל קונספטואלי – שמתאר בצורה “טובה” את המוצר, ואת הביזנס, בהקשר של תוכנה.
- מיפוי המודל הקונספטואלי ל Design (כלומר: מבנה של מערכת תוכנה) – אזור זה מכיל שורה של רעיונות כיצד למפות תיאור של מודל עסקי לתוכנה. אזור זה מתחלק גם הוא לשני שלבים:
- “תכנון אסטרטגי”
- “תכנון טקטי”
הרעיון של מודל קונספטואלי לכתיבת תוכנה (עסקית) הוא לא חדש בכלל, אבל DDD חידד ושיפר כמה רעיונות.האזור השני של DDD הוא מורכב, מפורט, והאמת: גם לא כ”כ עדכני (כי טכנולוגיות השתנו, וסגנון ה Microservices פותר חלק מהדילמות). למען האמת, טכניקות ה design של DDD הן מעניינות – אך לא הוכחו כמוצלחות במיוחד בפועל. יש שם רעיונות יפים, ושכדאי להכיר – אבל יותר כרעיונות בודדים ולא כ Framework סדור.
הספר מציג Framework למימוש המודל הקונספטואלי כתוכנה, ומשתמש בעקרונות Object-Oriented בשילוב של רעיונות שאינם Object-Oriented אך הוכיחו את עצמם לאורך שנים. מבנים כמו Aggregate ו/או Repository – הם לא “Object Oriented טהור”. שווה אולי לציין שספרי מידול קודמים נהגו לחתור למודל טהור של “אובייקטים בזיכרון” ולא התייחסו כ”כ לבעיות הארציות כמו – שמירה לבסיס נתונים רלציוני. זה מלכלך את המודל.
למשל: 1.0 EJB היה אמור להיות Framework שמאפשר למתכנת-הממדל לחשוב על אובייקטים ולא לדאוג לבעיות כמו אכסון ושמירה. זה עבד טוב כל עוד היו פחות מ 10 משתמשים במערכת 😉
רעיון כמו Event Sourcing (אותה סקרתי בפוסט קודם) – הוא לא ממש Object-Oriented – אך הוא רעיון מוצלח ושימושי.
Firewall, מודול לזיהוי פנים, או להתאמה של פרסומת ללקוח – הן לא מערכות “עסקיות”, וכנראה פחות מתאימות לשימוש ב DDD.
עוד כמה מילים על “המודל”
המודל הוא תיאור של מציאות (עסקית) מסוימת.
מקובל לתאר אותו ב UML – אבל לא חייבים. מה שחשוב שהמודל יהיה ברור, ושלא משתמע לשני פנים.
אני מעדיף את המונח (המקובל) “מודל קונספטואלי” בכדי לתאר את המודל שהוא רעיוני ולא ממש קוד.
במודל קונספטואלי הישויות הם רעיונות: “חשבונית”, “לקוח”, “ספק” – ולא משנה כ”כ כיצד ממשים אותם. בתוך המודל אפשר לשכוח לרגע מ Scalability, בסיסי נתונים, או בעיות של רשתות תקשורת.
בהמשך הפוסט אשתמש במונח “מודל” – כאשר הכוונה היא למודל קונספטואלי.
שאלה: איזה מודל מהבאים מוצלח יותר, לתיאור ארגון גדול במערכת ממוחשבת לניהול פרויקטים?
מודל ראשון:
![]() |
מקור: https://martinfowler.com/apsupp/accountability.pdf |
או אולי המודל השני?
כמובן שכמו Design של תוכנה, אין “מודל טוב” או “מודל רע”. יש מודל מתאים יותר ומודל מתאים פחות לצורך הקונקרטי.
כשיוצרים מודל זה לא נכון לתאר את המציאות המורכבת במלואה – העולם שלנו הוא מורכב ומלא פרטים. העניין הוא בזיקוק העיקר והדגשת התובנות החשובות לגבי המודל.
כלל מנחה: “!Make the model as simple as possible – but no simpler”
אני אוהב את הדוגמה של אריק על המפה (העתיקה) של חבל ארץ בסין:
מבחינה גאוגרפית המפה היא מעוותת, חסרה פרטים רבים, ומלאת שגיאות!
מבחינת שבט שגר בחבל הארץ הזה היא מאירת עיניים ושימושית למדי – היא מציינת באיזה כיוון מתגורר כל שבט. היא מדגישה את מה שחשוב למשתמשים שלה! מתארת את “הביזנס”.
מפה מודרנית, “מלאה”, ו”מדויקת” – היא כמעט חסרת-תועלת לאותו משתמש.
על אומנות ה Modeling
שימו לב שהרעיונות של DDD לא מתיישבים בקלות עם כמה מתודולוגיות נפוצות – למשל SCRUM.
ב SCRUM, יש תפקיד בשם Product Owner שהוא המתורגמן בין אנשי הביזנס / הלקוחות – למתכנתים. כשיש PO אין צורך לדבר עם לקוחות: ה PO מדבר עם כל הלקוחות, מרכז את התובנות שלהם לתמונה אחידה וברורה – שקל למפתחים לצרוך.
DDD מציגה רעיון שנקרא Hands-On Modeler – המתכנת (להלן “Hands-On”) צריך להיות גם ה Modeler – האדם שמגדיר את המודל, מבין אותו, ומכאן מבין גם את הביזנס ונמצא בקשר עם לקוחות המערכת. זה לא צריך להיות כל מפתח (Every) אלא ייצוג הולם של אנשים מצוות הפיתוח (Any).
שנייה אחת. יש כבר רעיון שכל מפתח צריך להיות איש ה QA של עצמו (TDD?), או הרעיון שכל מפתח צריך להיות איש ה Operations של עצמו (Continuous Deployment?).
האם באמת מפתח יכול להיות גם QA, גם איש Operations, וגם איש Product – ועוד להספיק לכתוב קוד משמעותי?!
כנראה שלא ממש. הסיבה שכל אחת המתודולוגיות הללו “מלבישה” למתכנת “כובע” נוסף חדש – היא כי ממשקי עבודה (“Seams”) הם מקור לתקשורת נחותה יותר (“טלפון שבור”) ואופטימיזציה לוקאלית בכל צד – מתכון מוכך לבעיות.
- ארגונים שאיכות היא עניין מאתגר ומורכב במיוחד עבורם – כנראה ידרשו מהמפתחים גם לעשות QA.
- ארגונים שסביבת הפרודקשיין שלהם מאתגרת – כנראה יידרשו מהמפתחים לעשות גם Operations.
- ארגונים שהתאמת המוצר ללקוח היא חלק מאתגר במיוחד בעיסוק שלהם – יאמצו DDD ו/או Lean Startup.
- נחדד: אם הלקוח הוא consumer אחד מני רבים – כנראה שגישת ה Lean Startup ושורה של ניסויים – היא עדיפה. אז נרצה שמפתחים יציעו ויבצעו ניסויים.
- אם הלקוח הוא Domain Expert שיש מעטים כאלו שאפשר לגשת ולתחקר אותם – זה ה Sweet Spot של DDD.
ארגונים שדורשים מהמפתחים שלהם להיות גם וגם וגם – הם כנראה קצת מבולבלים, ולא הבינו עדיין היכן הפוקוס שלהם … 😉
נחזור ל DDD, ופיתוח תוכנה עסקית, שהלקוחות שלה הם עובדי-ידע בעלי מומחיות בתחום כזה או אחר.
ללקוחות יש תפיסה מסוימת של העולם שהם הסכימו בינם לבין עצמם עליה.
בד”כ יש “תפיסה מקובלת בתחום”, עם “התאמות מקומיות” (שחשובות לא פחות, אולי יותר).
אם זו הביזנס הוא תחנת מוניות מוניות אז ה Domain Experts חושבים על “היצע” (נהגים) ו”ביקוש” (נוסעים) ועל אחוז ההיענות של נהגים לנסיעות ו/או אחוז ההזמנות שסופקו. הדרישות החדשות שלהם לתוכנה שנכתבת – יגיעו בעולם המושגים הזה.
כאשר המערכת (תוכנה) איננה ממופה 1:1 למודל הקונספטואלי של הלקוחות – יישום דרישות חדשות עשוי להיות מפרך, ומרובה טעויות:
“אנו רוצים שתשלום יהיה גם במזומן או ב Paypal”
– “אין מצב. אנחנו תומכים רק בכרטיסי אשראי. שינוי עכשיו יהיה מ-ט-ו-ר-ף!”
“אנו רוצים שהזמנה אחת תוכל להכיל שתי נסיעות: הלוך וחזור”
– “אנחנו נאלץ ליצור שתי הזמנות – אחת גלויה ואחת חבויה ולקשר אותן איכשהו. ולחייב שזה אותו נהג ואותו נוסע ועוד כמה דברים…”
– “הממ… באמת? זה ממש חשוב? נצטרך 8 שבועות בכדי לממש את זה. אולי אפשר לוותר?”
“למה מורכב? תצרו נסיעה עם נוסע אחר. נשים שדה ב UI להזין את זה”
– “אתם לא מבינים. זה ממש מסובך! צריך שה HiddenOrder עכשיו יהיה ExpandedHiddenOrder שנשמר בטבלה אחרת וגם מכיל נוסע שיכול להיות אחר, והטיפוס הזה מדלג על ה Validations כבר יש לנו במערכת עבור הסיפור ההוא של נסיעת חזרה פשוטה…. ו….. ואז….”
“??? …. אנחנו לא ממש מבינים למה זה הפעם מורכב. תוכנה זה תחום בלתי-צפוי – מסתבר…”
כדי לבנות תוכנה שממופה 1:1 למודל הקונספטואלי – אנחנו צריכים להבין את המודל (הנפלא!) הזה שנמצא במוחותיהם של ה Domain Experts. הבנה שלו תאפשר לנו לקבל דרישות חדשות בהרמוניה.
אם המודל מוכר רק ל PO או לארכיטקט – Corruption הוא בלתי-נמנע.
העקרונות הראשיים של DDD (בקצרה)
איך ממדלים בצורה טובה? – הייתי ממליץ להתחיל עם הספר Analysis Patterns.
- המודל הוא עמוד השדרה של השפה המשותפת. הוא אמור להכיל את המונחים החשובים.
- אנו מקפידים על שמות נכונים של אובייקטים, טבלאות בבסיס הנתונים, משתנים וכו’ – ע”פ השפה המשותפת.
- זה גם נכון למסמכים, מיילים, ודיונים. שימוש בשפה “תקנית” מצופה מכולם.
- כאשר הקוד יוצא מסנכרון עם השפה – מיישרים אותו חזרה בעזרת Refactoring.
- אם לקוחות משתמשים במונח הרבה – כדאי שזה יהיה אובייקט מרכזי במערכת. אם לא – זהו smell לטעות מידול.
- אם לקוחות משתמשים במונחים דומים לחלופין – חשוב להבהיר את ההבדל! או שיש פה תובנה משמעותית – או שיתיישרו למונח יחיד.
- בגדול, הלקוחות (ליתר דיוק: ה Domain Experts מהביזנס) הם אלו שמכתיבים את השפה. הם מעבירים את הידע שברשותם לפיתוח.
- “נוסע” בהקשר התחום של אנשי הכספים.
- “נוסע” בהקשר התחום של אנשי המכירות.
אין איזה פורמט חכם או שיטה מיוחדת לנהל את ה Context Map, עד כמה שזכור לי. כדאי שהניהול יהיה הגיוני ואינטואיטיבי.
כמה קשיים ביישום DDD
- קבוצת ה R&D לעתים נתפסת ע”י ההנהלה כמרכז עלות ולא כמרכז רווח: נכון, החברה אולי מרוויחה מהתוכנה שכבר כתובה, אבל הדגש כעת הוא על צמצום בעלויות הפיתוח (פחות עלויות תחזוקה, פיתוח פיצ’רים מהר / זול יותר) ולא בהשקעה להגיע ל”פיצ’ר שתופס בצורה מעמיקה את הביזנס”.
- מפתחים שקועים במידה רבה בטכנולוגיה ובמחשבה כיצד להתנסות / לשלב טכנולוגיה חדשה במערכת – יותר מאשר איך ליצור תוכנה נכונה יותר לביזנס.
טכנולוגיות חדשות הן מפתח להתחדשות והתייעלות, אך כאשר המיקוד הוא “אימוץ טכנולוגיה החדשה” ולא החדשנות וההתייעלות – התוצאה היא בהתאם. - ה DB כבר כמה עשורים מקבל מרכז כובד מוגזם בתכנוני המערכת. נכון: הוא כלי רב יכולות, וקל לפשט בעיות ועסקיות ולחשוב עליהן כבעיות של data (“כיצד לוקחים את הנתון הזה, מבצעים עליו עיבוד ומעבירים אותו לשם”) – אבל ההתייחסות ל DB כמרכז המערכת מסתירה מאיתנו תובנות עמוקות יותר על המערכת והביזנס, ולרוב מונעת מ “תכנונים יעילים במיוחד” של המערכת מבחינת DDD – מלהתפתח.
- מבנה המערכת לא מתמפה בצורה פשוטה למודלים העסקיים.
- הסיבה: המפתחים בוחרים במידול / מבנה מערכת מתוך חשיבה טכנית גרידא. הם בוחרים בשמות לאובייקטים ולמודולים, כך שיהיו נוחים להם עם הידע הנוכחי שהם – “ידע” שלרוב הוא בעצם בורות עמוקה (סליחה סליחה!) ברזי הביזנס.
- התוצאה: חלק מהדרישות העתידיות שיגיעו למפתחים יהיו “הפתעת יום כיפור”: הם תכננו את המערכת עם גמישויות X – אבל הדרישות סובבות מסביב לגמישויות Y. השינוי הנדרש הוא ארוך ויקר והמפתחים יעמדו על הרגליים האחוריות להסביר לביזנס ש”הדרישה שלהם לא סבירה”, וש”יאלצו להסתדר בלי”. הם עלולים להיות כמו כלב תוקפני שיש להיזהר ממנו.
מותר להעמיד את אנשי הביזנס בפני אי נוחות – מלבד הפעמים שאסור. - תוצאה בגרסה “משופרת”: המפתחים עובדים בחשיבת Lean. הם לא יצרו גמישויות X כלשהן – ולכן “תסריט יום כיפור” הוא פחות מזעזע עבורם. הם פשוט יבצעו את השינויים הנדרשים במערכת על מנת ליצור גמישות Y. הם אדישים לשינויי הדרישות והם לא יעצרו או יילחמו בביזנס – אבל הם גם יכולים לבזבז זמן רב ב Refactorings הלוך ושוב – כי הם לא מצליחים “להריח” להיכן הביזנס לוקח אותם. הם כמו כלב ידידותי אך עיוור.
![]() |
ה “System Flexibility Challenge” בין R&D לביזנס, מודגם במטאפורה של מכאניקה.
המפתחים מספקים גמישויות x1 ו x2 – ושמחים שענו לצרכי הביזנס, אבל הביזנס בעצם זקוק ל y4 ו y2.
|
Communications usually fails, except by accident” — Osmo Wiio”
![]() |
מפתח שניגש ל DDD בפעם הראשונה, עשוי לדמיין את האינטראקציה כך:
ה Domain Expert מבין עניין. לאחר שיחת היכרות של שלושים דקות הוא מסדר לנו את הדברים בראש ב Domain שלו. משם נפגשים עוד כמה פעמים, תוך כמה מפגשים – אנחנו כבר “מביני עניין” ב Domain! אנחנו מגדירים במשותף מודל – וזה ממש עובד יפה!. משם ממשיכים לפיתוח, אנחנו עושים את העבודה שלנו (נהדר, כרגיל) ויוצאת מערכת פצצה שמזניקה את הביזנס – וה Domain Experts אסירי תודה לעד!
הללויה!!
רק שזה לא עובד כך.
סיכום
כמו בפוסטי עבר: אם אתם מעוניינים רק לספר לחברים שאתם עושים DDD וזה “מה-זה מגניב!”, אתם יכולים להתעלם מכל הנאמר בפוסט – ופשוט להצהיר זאת כבר עכשיו. אני מרשה.
אם חשבתם שתצאו מהפוסט הזה עם Patterns מגניבים שאפשר לממש מחר בבוקר (בעולם המיקרו-שירותים) – ייתכן ואכזבתי אתכם. סליחה.
הפוטנציאל של DDD להשיג שיפור משמעותי במקצוע התוכנה – הוא גדול, במיוחד מסביב לאזור המידול. הבעיה: קשה למצוא את האנשים שיפיקו ממנו את המירב. ייתכן גם שהם לא העובדים הטיפוסים של סטאראט-אפ מגניב, שבדיוק מחלקים את הזמן בין משחק בין Vue.js ו Docker.
אציין משהו לא מגניב: אני נתקל בפעילות רבה במיוחד בכל הנוגע ל DDD דווקא בעולם הדוטנט / #C (למשל: naked objects – אבל גם הרבה מעבר לזה). אני מניח שמפתחים הרבה יותר “תוכנה עסקית” על סביבת NET. של מייקרוסופט מאשר על סביבות אחרת – או לפחות הם מזהים את עצמם ככאלה.
אני דיי בטוח שחלק נכבד מה”סטארט-אפים המגניבים” עושים גם תוכנה עסקית, ויכולים להיעזר ברעיונות של DDD בכדי לעבוד טוב וחכם יותר.
למה אני אומר את זה? – אני זקוק לפוסט המשך בכדי להסביר…
שיהיה בהצלחה!
יש לך קוראים שכותבים בC#…תודה רבה על הפוסטים המעניינים.כלומר בשביל לממש DDD, צריך לשחרר את התלות הכבידה בDB, ולפקס את המפתחים בביזנס של החברה.המיפוי עצמו – נשמע הגיוני שיהיה בשפה של הביזנס. אבל מה עם זה שזה כבר מסד נתונים מלא אצל לקוחות? היתה התיחסות בספר לכך שהמודל הוא דינאמי? בגדול עד היום היתה לי אסוציאציה שDDD – זה להפסיק לכתוב פרויקט לDAL, BL וGUI. אלא להתמקד בחלוקה של הביזנס. שמבנה הקוד והפרויקטים יהיו בהתאמה של הביזנס. אם אני לא טועה בקשר, זה נראה לי שאיפה לכל ארגון…שוב, תודה רבה על הפוסט ועל הידע הרחב שאתה מגיש.
תודה רבקה!> אבל מה עם זה שזה כבר מסד נתונים מלא אצל לקוחות? היתה התיחסות בספר לכך שהמודל הוא דינאמי? לא הבנתי: האם השאלה היא מה עושים כאשר יש מערכת קיימת ואז רוצים ליישם DDD?> להפסיק לכתוב פרויקט לDAL, BL וGUI…בגדול הגישה בחלק השני של הספר היא מבנה בו ה BL מורכב מאובייקטים שמתמפים יפה למודל הקונספטואלי והקשרים שבו – אובייקטים בזכרון, לצורך העניין – המכילים את כל הלוגיקה.ה DAL ממומש כסט של Repositories:- כל Repository \”טוען\” (או \”שומר\”) אובייקט שלם, מסוג מסוים – לזכרון, כך שאין צורך לעבוד עם SQL או שפת שאילתות ש\”מעוותת\” את התפיסה של המודל. שיטוט (navigation) בין האובייקטים נעשה ע\”י קריאה ל\”פרמטר\” (פרשנות מקובלת: אובייקט Proxy כמו של ה GoF) – על האובייקט שיוצרת instance של האובייקט שקשור אליו (מביאה אותו מה Repository שלו).יש ספריות ORM שיכולות לספק התנהגות דומה (אם כי בד\”כ הן מספקות הרבה יותר).ליאור
כן,בשיטת Lean, כל הזמן לקוחים בחשבון שינויים.וכאשר הDB חייב להתאים למושגים הקונספטואליים, זה יוצא בעייתי
פוסט מצויין ליאור!
תודה רבה!