כיצד לפתח מערכות תוכנה גדולות בלי להסתבך בדרך

ליאור בר-און מסביר מה עומד מאחורי Domain Driven Design, וכיצד אתם יוכלים להפיק ממנו את המקסימום

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

הקדמה

הקשר בין גודל התוכנה לסיבוכיות שבה הוא קשר ברור וידוע.

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

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

כיצד ניתן לשנות זאת?

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

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

ואיך בכלל יוצרים מערכת פשוטה יותר? “חושבים פשוט”? “עושים KISS”? “עובדים לאט ובזהירות”?

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

ובכן, היכונו! אוונס וה-DDD (כלומר [Domain Driven Design [1) הולכים ללמד אתכם כיצד לקבל דרישות איכותיות יותר וכיצד לבנות מערכת שתהיה גמישה יותר לקבלת דרישות עתידיות. הדרך להתמקצעות היא לא פשוטה, אך כל מי שיש לו גישה לדרישות של לקוחות וקצת חשיבה מופשטת יכול די מהר להגיע לתוצאות ראשונות.

מעט היסטוריה

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

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

על התהליך הנפוץ לתכנון תוכנה

לא משנה אם אתם עובדים Waterfall או Agile, קרוב לוודאי שהמתכנתים לא אוספים את הדרישות מהלקוח בעצמם. יתרה מכך, גם שמדברים עם הלקוח לא תמיד יהיה זה המומחה העסקי. ייתכן ואתם מדברים עם מנהל התפעול בבנק (“לקוח”) שרוצה מערכת לניהול משכנתאות, אבל אתם לא מדברים עם מי שמתעסק עם זה בפועל (Domain Expert). על מנת לפשט לכם את הנושא, מנהל התפעול משתמש במושגים שיותר קלים להבנה. ה-PM לוקח צעד אחד הלאה ומשתמש במושגים יותר מקובלים מהעולם-הלא-מקצועי כי “מפתחים יאבדו כיוון אם נציף אותם בכל המידע הזה”. זהו הרי תפקידו.

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

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

מקור: softwarearchiblog

כפי שסיפרנו ה-Domain Expert (אשתמש ב-DE מעכשיו) משתמש בטרמינולוגיה משלו וכל שאר הגורמים בדרך מתרגמים, שלב אחר שלב, כך שלמפתחים יהיה ברור מה “עליהם לעשות”. הכל טוב, לזמן מה – עד אשר מגיע שינוי לא-צפוי בדרישות:

מקור: softwarearchiblog

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

בואו נעצור לרגע: אנו מדברים במושגים (“חשבונית”) ובתסריטים (Use-Cases) אך מאחורי כל אלה יש לנו מודל תפיסתי (Conceptual Model) שמתאר איך הדברים מתרחשים. בני-אדם, כמונו, נוטים להרגיש אי-נוחות בעת שהם עוסקים בנושא לא מוכר. כתרופה, מנגנוני החשיבה שלנו גורמים לנו להשלים, באופן כמעט מיידי, את סט העובדות שניתנו לנו למודל תפיסתי הגיוני (מבחינתנו). איכות העובדות שהועברה לנו, כשרון ומזל יכתיבו עד כמה נכון המודל שבנינו. לא מעט ריבים / חוסרי-הבנה נוצרים בגלל הפער שבין המודל של אדם א’ לאדם ב’, שניהם ניזונו מאותן עובדות.

“הפתרון הרשמי”

אז מה עושים? אחד העקרונות המרכזיים של DDD הוא שפה-רוחבית (ubiquitous language). על מישהו, ה-business analyst, לחפור ללמוד ולהגדיר עם ה-DEs שפה אחידה ומוסכמת על פיה כולם יעבדו, שפה שבעצם תגזר מתוך Conceptual Model ברור ומלוטש (במידת האפשר).

מקור: softwarearchiblog

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

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

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

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

אז מה יותר יציב מרשימת use-cases ומסכי UI? היכן אנו יכולים להשקיע בלמידה של המקור ממנו באות הדרישות? ידע יציב שאינו נוטה להשתנות בקלות?

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

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

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

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

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

דרך מקובלת ונוחה לתאר מודל היא תרשימי Class Diagram של UML. כמובן שזו רק דרך אחת, אפשר בכל תרשים חופשי, טקסט וכו’.

חזרה למציאות

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

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

צרו, ועבדו עם מודל קונספטואלי

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

הקשיבו לשפה

כלל #1: אם בשיחה עם הלקוח (DE), הלקוח משתמש הרבה במושג (למשל, “חשבונית”) ואין לכם אובייקט מרכזי בשם “חשבונית” – זהו סימן לפער במודל. תקנו את המודל שייתן משקל מתאים למושגים החשובים בהם משתמש הלקוח בשיחה היום-יומית.

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

זכרו: “(You can run, but you cannot hide (a bad conceptual model”. אם “תשקרו” את המערכת ותעבדו עם מודל לא מדוייק, זה יחזור אליכם בדמות תחזוקה קשה ודרישות עתידיות הקשות ליישום.לדוגמא: תיאור של מחשב עם 2 כתובות IP כשני מחשבים עם אותו השם, כל אחד עם כתובת IP אחת – אולי יקצר את הפיתוח בשלב הראשון, אך יחזור אליכם כמוברנג כחלק מדרישות עתידיות. ניסיתם “לשקר” במודל.

סיכום

למי שהתנסה בהצלחה במידול בכלל או DDD בפרט, מידול נראה חלק הכרחי בבנייה של כל מערכת. תורת המידול אינה נפוצה ואינה קלה – אך היא מביאה תוצאות ממשיות. המקור הטוב ביותר שאני נתקלתי בו עד היום הוא הספר Analysis Patterns של Martin Fowler, ספר קצת לא-מסודר אך בעל תובנות עמוקות.

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

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

פוסט זה הופיע לראשונה בבלוג ארכיטקטורת תוכנה www.softwarearchiblog.com

Avatar

ליאור בר-און

ליאור בר-און הוא Chief Architect בחברת סטארטאפ ישראלית גדולה.

הגב

3 תגובות על "כיצד לפתח מערכות תוכנה גדולות בלי להסתבך בדרך"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

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

סידור לפי:   חדש | ישן | הכי מדורגים
tom
Guest
כמה הערות ברשותך 1.לפני הכל הכי חשוב,תודה על המאמר ועל הזמן שהשקעת לטובת הקהילה. 2.אין דבר כזה מודל מדויק או נכון ,כי מודל הוא דבר סובייקטיבי,אני מעדיף להשתמש במונח “מודל מתאים”,כאשר ההגדרה של “מתאים” היא מאוד רחבה ולאו דווקא קשורה לדרישות הפונקציונליות אלא למגוון רחב של אילוצים למשל, דבר זניח, כמו הדד ליין….אני צריך להוציא HF ללקוח שמוכן לשלם מיליון דולר אם הוא יצא תוך שבוע…האם אני אתעקש על איכות?!? לא בטוח….קודם אוציא ואחרי זה אחזור ואתקן את הדרוש 3.אני חייב להודות שלמרות שיש לי את הספר כמה שנים,לא הצלחתי לסיים אותו הוא פשוט משעמם כמעט כמו הספר של של… Read more »
ליאור
Guest

תודה על התגובה המפורטת, אנסה להתייחס לכמה נקודות בקיצור:
1. לגבי מודל, כמו שנאמר בפוסט “המודל לא צריך להיות מושלם או מפורט במיוחד – הוא צריך להיות נכון לשם המטרה ומועיל”. נושא הדיוק שהזכרתי הוא לא שהמודל צריך להיות שלם, אך חשוב לפשפש ולהתייחס גם לפרטים הקטנים – כי מאחורי כל אחד מהם עשויה להיות תובנה משמעותית.
2. קוד שדומה למודל הוא שאיפה, וברור שבקוד יש לקחת שיקולים שלא קיימים בעולם האמיתי (כמו ביצועים).
3. Agile מכתיב cycles קצרים ותהליך למידה. “Eliminate Waste” הוא ערך עליון. אלו דרכים מצויינות להמנע מ over-engineering וליצור מערכת פשוטה יותר.

tom
Guest
לפי דעתי כל מה ש AGILE מכתיב זה עקרונות התנהגותיות תקשרותיות וניהוליות שאין להם דבר וחצי דבר עם איכות תוכנה וזו הנקודה שאני מנסה להעביר לעמיתיי. מה שציינת לא מבטיח לפי דעתי תוכנה איכותית,אלה רק ססמאות שמהוות מסגרת בה אפשר להתנהל AGILE הוא לא MAGIC STICK .אם הצוות שלך(הכוונה באופן כללי לא שלך דווקא) אינו מקפיד על INTERNAL QUALITY ע”י שימוש במתודולוגיות פיתוח וארכיטקטורה נכונות ויישום עקרונות כגון SOLID ו HIGH COHESION LOOSE COUPLING וכולי,לא רק שהם לא כותבים OO זה לא יעזור כמה ה CYCLE קצר אני מצטער אם אני נשמע כמו הילד שצעק המלך עירום(המלך במקרה הזה הוא… Read more »
wpDiscuz

תגיות לכתבה: