เครื่องมือเร่งความเร็วและการบริหาร project DDD
การใช้ Domain-Driven Design (DDD)Domain-Driven Design (DDD)แนวทางพัฒนาซอฟต์แวร์ที่เน้นสร้าง domain model ซึ่งเข้าใจกฎและกระบวนการของธุรกิจอย่างลึกซึ้ง แล้วเขียนลงใน code จริง บัญญัติโดย Eric Evans (2003) แบ่งเป็น Strategic และ Tactical DesignStrategic Design คือการออกเดินทางเพื่อ เรียนรู้ให้ลึก ว่าธุรกิจทำงานอย่างไร แล้วจึงสร้าง model ซอฟต์แวร์ขึ้นจากความเข้าใจนั้น มันคือวงจรของการเรียนรู้ ทดลอง ตั้งคำถาม เรียนรู้เพิ่ม แล้วสร้าง model ใหม่อีกครั้ง — เราต้องบดและกลั่นความรู้ปริมาณมหาศาลให้กลายเป็น design ที่ตอบโจทย์เชิงกลยุทธ์ขององค์กรได้จริง โจทย์ที่ยากคือ เราต้องเรียนรู้ให้เร็ว ในอุตสาหกรรมที่ทุกอย่างเร่งรีบ เวลาเป็นตัวกำหนดการตัดสินใจแทบทุกเรื่อง (อาจมากเกินกว่าที่ควรด้วยซ้ำ) และถ้าส่งงานไม่ทันกำหนดหรือเกินงบ ไม่ว่าซอฟต์แวร์จะดีแค่ไหนก็ดูเหมือน “ล้มเหลว” ในสายตาคนอื่น
หลายคนพยายามโน้มน้าวฝ่ายบริหารว่า การประมาณเวลาของ project ส่วนใหญ่นั้นไร้ค่าและใช้ไม่ได้จริง แต่ในความเป็นจริง ลูกค้าแทบทุกรายที่ Vaughn Vernon ทำงานด้วยก็ยังถูกกดดันให้ส่งมอบภายในกรอบเวลาที่ชัดเจนอยู่ดี ซึ่งบังคับให้เกิดการ timebox ในกระบวนการออกแบบและพัฒนา อย่างดีที่สุดมันก็เป็นการดึงกันไปมาระหว่างฝ่ายพัฒนาและฝ่ายบริหารอยู่ตลอด
ปฏิกิริยาที่พบบ่อยต่อแรงกดดันนี้คือการพยายาม “ประหยัด” ด้วยการ ตัดการออกแบบทิ้ง — แต่จำบทแรกได้ไหม? design เป็นสิ่งที่หลีกเลี่ยงไม่ได้ เราจะทำมันแย่จนได้ design ที่แย่ หรือจะทำมันให้สำเร็จด้วย effective design (หรือกระทั่ง design ที่ดี) ก็ได้ ดังนั้นสิ่งที่ควรทำคือ เผชิญกับข้อจำกัดด้านเวลาตรงๆ แล้วออกแบบในแบบที่เร่งความเร็วได้ บทนี้จึงรวบรวมเครื่องมือเร่งการออกแบบและบริหาร project ที่มีประโยชน์มาก เริ่มจาก EventStorming แล้วปิดท้ายด้วยวิธีนำผลลัพธ์จากเวิร์กช็อปนั้นไปสร้าง การประมาณการที่มีความหมายและทำได้จริง
EventStorming — ออกแบบเร็วด้วยกระดาษโน้ตติดผนัง
หัวข้อที่มีชื่อว่า “EventStorming — ออกแบบเร็วด้วยกระดาษโน้ตติดผนัง”EventStormingEventStormingเวิร์กช็อปแบบร่วมมือ (Alberto Brandolini, 2013) ใช้กระดาษโน้ตสีติดบนผนัง: ส้ม=event, น้ำเงิน=command, เหลือง=aggregate ฯลฯ เพื่อค้นพบ model และขอบเขตของ contextProcess คือเทคนิคออกแบบแบบรวดเร็วที่ออกแบบมาเพื่อดึงทั้ง ผู้เชี่ยวชาญธุรกิจ (Domain Expert)Domain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design และนักพัฒนาเข้าสู่กระบวนการเรียนรู้ที่ไหลลื่นและรวดเร็ว จุดโฟกัสคือ กระบวนการทางธุรกิจ ไม่ใช่คำนามและโครงสร้างข้อมูล
ก่อนจะรู้จัก EventStorming, Vernon เคยใช้เทคนิคที่เรียกว่า event-driven modeling ซึ่งอาศัยการสนทนา, การสร้างสถานการณ์รูปธรรม (concrete scenario) และการสร้าง model ที่เน้น event ด้วย UML แบบเบามาก ปัญหาคือคนฝั่งธุรกิจน้อยรายที่อ่าน UML ออก งานสร้าง model จึงตกอยู่กับนักพัฒนาเป็นหลัก จนไม่ดึงผู้เชี่ยวชาญธุรกิจเข้ามามีส่วนร่วมโดยตรงได้อย่างที่ควร
Vernon ได้เรียนรู้ EventStorming ครั้งแรกจาก Alberto Brandolini ผู้ซึ่งครั้งหนึ่งขณะที่เวลาไม่พอ ตัดสินใจ “โยน UML ทิ้ง” แล้วหันมาใช้ กระดาษโน้ต (sticky notes) แทน นั่นคือจุดกำเนิดของวิธีเรียนรู้และออกแบบซอฟต์แวร์อย่างรวดเร็วที่ทำให้ทุกคนในห้องมีส่วนร่วมโดยตรง ข้อดีของมันมีมากมาย:
- เป็นการลงมือจับต้องจริง ทุกคนได้กระดาษโน้ตหนึ่งปึกกับปากกาหนึ่งด้าม และมีหน้าที่ร่วมเรียนรู้และออกแบบไปด้วยกัน คนฝั่งธุรกิจกับนักพัฒนายืนอยู่บนพื้นที่เท่าเทียมกัน ทุกคนช่วยกันป้อน ภาษากลาง (Ubiquitous Language)Ubiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design
- โฟกัสที่ event และกระบวนการทางธุรกิจ ไม่ใช่ที่ class หรือฐานข้อมูล
- เป็นภาพ (visual) ล้วนๆ ตัด code ออกจากการทดลอง ทำให้ทุกคนอยู่บนระนาบเดียวกันในการออกแบบ
- เร็วและถูกมาก เราสามารถ “พายุไอเดีย” ออกมาเป็น Core DomainCore Domainsubdomain ที่สำคัญและสร้างความได้เปรียบในการแข่งขันมากที่สุด เป็นเหตุผลที่เราต้องสร้างซอฟต์แวร์เองแทนการซื้อ ควรทุ่มทีมเก่งที่สุดลงตรงนี้Strategic Design ฉบับร่างได้ภายในไม่กี่ชั่วโมง แทนที่จะกินเวลาเป็นสัปดาห์ ถ้าเขียนอะไรไปแล้วไม่เวิร์ก ก็แค่ขยำกระดาษโน้ตทิ้ง ต้นทุนของความผิดพลาดแค่หนึ่งหรือสองสตางค์ จึงไม่มีใครหวงที่จะแก้ไขเพราะ “ลงแรงไปแล้ว”
- ทีมจะเกิด breakthrough ในความเข้าใจ เสมอ บางคนมาด้วยความมั่นใจว่าเข้าใจ core domain ดีอยู่แล้ว แต่ไม่ว่าอย่างไรก็จะกลับออกไปพร้อมความเข้าใจที่ลึกขึ้นและมุมมองใหม่ๆ เกี่ยวกับกระบวนการทางธุรกิจเสมอ
- ทุกคนได้เรียนรู้บางอย่าง ไม่ว่าจะเป็นผู้เชี่ยวชาญธุรกิจหรือนักพัฒนา ก็จะเดินออกไปพร้อมความเข้าใจ model ที่คมและชัด หลาย project มีคนจำนวนหนึ่งที่ไม่เข้าใจว่ากำลังทำอะไรอยู่จนกระทั่งสายเกินไปและความเสียหายฝังอยู่ใน code แล้ว การ “storm” model ออกมาช่วยให้ทุกคนเคลียร์ความเข้าใจผิดและเดินไปในทิศทางเดียวกัน
- ระบุปัญหาได้เร็วที่สุด ทั้งใน model และในความเข้าใจ รีดความเข้าใจผิดออก แล้วเปลี่ยนผลลัพธ์ให้เป็นมุมมองใหม่ ทุกคนในห้องได้ประโยชน์
- ใช้ได้ทั้งระดับ big-picture (ภาพรวม) และ design-level (ระดับออกแบบ) — แบบ big-picture จะหยาบกว่า ส่วน design-level จะนำไปสู่ artifact ของซอฟต์แวร์ที่ชัดเจนขึ้น
- ไม่จำเป็นต้องจบในครั้งเดียว เริ่มด้วย session สองชั่วโมง พักผ่อน นอนคิด แล้วกลับมาอีกหนึ่งหรือสองชั่วโมงวันถัดไปเพื่อขยายและกลั่น ทำแบบนี้วันละสองชั่วโมงสักสามถึงสี่วัน จะได้ความเข้าใจ Core Domain และจุดเชื่อมต่อกับ SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design โดยรอบอย่างลึกซึ้ง
- คนที่ใช่ คือสิ่งจำเป็น — ต้องมี ผู้เชี่ยวชาญธุรกิจDomain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design และนักพัฒนาที่จะลงมือทำ model ทุกคนถือคำถามคนละบางส่วนและคำตอบคนละบางส่วน จึงต้องอยู่ในห้องเดียวกัน
- ทุกคนต้อง เปิดใจ ปลอดจากการตัดสินที่เข้มงวด ความผิดพลาดที่พบบ่อยที่สุดคือพยายาม “ถูกต้องเร็วเกินไป” ควรตั้งใจสร้าง event ให้มากเกินไว้ก่อน เพราะนั่นคือสิ่งที่ทำให้เราเรียนรู้มากที่สุด เดี๋ยวค่อยกลั่นทีหลัง ซึ่งทำได้เร็วและถูก
- เตรียม กระดาษโน้ตหลากสี ให้มากพอ อย่างน้อยต้องมีสี: ส้ม, ม่วง/แดง, ฟ้าอ่อน, เหลืองอ่อน, ม่วงลิลลี่ (lilac) และชมพู ขนาดสี่เหลี่ยมจัตุรัส (ราว 7.62 ซม.) กำลังดี เลือกแบบเหนียวพิเศษจะดีเพราะไม่อยากให้โน้ตหล่นพื้น
- เตรียม ปากกาเมจิกหัวดำ ให้ทุกคนคนละด้าม หัวเล็กจะดีที่สุดเพราะลายมือจะคมชัด
- หา ผนังกว้างๆ เพื่อทำ model ความกว้างสำคัญกว่าความสูง พื้นที่ทำงานควรสูงราวหนึ่งเมตร ส่วนความกว้างยิ่งมากยิ่งดี ขั้นต่ำราว 10 เมตร — ถ้าไม่มีผนัง โต๊ะประชุมยาวหรือพื้นก็พอใช้ได้ แต่ผนังดีที่สุด
- หา กระดาษม้วนยาว มาแขวนบนผนัง (กว้างอย่างน้อย 10 เมตร สูง 1 เมตร) เพราะกระดาษโน้ตเกาะติดกระดาษได้นานกว่าเกาะบนไวต์บอร์ด สำคัญเมื่อจะทำ model เป็นช่วงๆ หลายวัน
เมื่อมีอุปกรณ์พื้นฐานและคนที่ใช่แล้ว ก็พร้อมเริ่ม ลองพิจารณาทีละขั้น
ขั้นที่ 1 — Storm กระบวนการทางธุรกิจด้วย Domain Event (โน้ตสีส้ม)
หัวข้อที่มีชื่อว่า “ขั้นที่ 1 — Storm กระบวนการทางธุรกิจด้วย Domain Event (โน้ตสีส้ม)”ออกแรง “พายุ” กระบวนการทางธุรกิจออกมาเป็นชุดของ Domain EventDomain Eventสิ่งที่ “เกิดขึ้นแล้ว” ใน domain ซึ่งส่วนอื่นสนใจ แทนด้วยอ็อบเจ็กต์ที่เปลี่ยนแปลงไม่ได้ ตั้งชื่อเป็นอดีต เช่น CargoWasRouted ใช้สื่อสารข้าม AggregateTactical Design บนกระดาษโน้ต สีส้ม (สีที่นิยมที่สุดสำหรับ Domain Event เพราะเด่นที่สุดบนพื้นที่ model) แนวทางพื้นฐานคือ:
- การสร้าง Domain Event ก่อนเป็นการตอกย้ำว่าเราโฟกัสที่ กระบวนการทางธุรกิจ เป็นอันดับแรก ไม่ใช่ที่ข้อมูลและโครงสร้างของมัน ทีมอาจใช้เวลา 10–15 นาทีในการอุ่นเครื่อง อย่าเพิ่งกระโดดข้ามขั้น
- เขียนชื่อ Domain Event แต่ละตัวบนโน้ตหนึ่งใบ ชื่อควรเป็น กริยาในรูปอดีต เช่น
ProductCreatedหรือBacklogItemCommitted - วางโน้ตบนพื้นที่ model เรียงตามเวลา จากซ้ายไปขวาตามลำดับที่แต่ละ event เกิดขึ้นใน domain หากยังไม่รู้ลำดับเวลาแน่ชัด ก็วางไว้ที่ใดที่หนึ่งก่อน แล้วค่อยหาว่ามัน “เกิดเมื่อไร” ทีหลัง
- Domain Event ที่เกิด ขนานกัน กับอีกตัวหนึ่งให้วางไว้ใต้ event ที่เกิดเวลาเดียวกัน — ใช้พื้นที่แนวตั้งแทนการประมวลผลแบบขนาน
- เมื่อเจอ จุดที่เป็นปัญหา ในกระบวนการเดิมหรือใหม่ ให้มาร์กชัดๆ ด้วยโน้ต ม่วง/แดง พร้อมข้อความอธิบายว่าทำไมจึงเป็นปัญหา จุดเหล่านี้คือจุดที่ควรลงทุนเวลาเรียนรู้เพิ่ม
- บางครั้งผลลัพธ์ของ Domain Event คือ Process ที่ต้องทำงาน (อาจขั้นตอนเดียวหรือหลายขั้นซับซ้อน) ให้จับมันลงโน้ต ม่วงลิลลี่ แล้วลากเส้นมีหัวลูกศรจาก Domain Event ไปยัง Process นั้น และจงสร้าง model event แบบละเอียดเฉพาะเมื่อสำคัญต่อ Core Domain เท่านั้น เช่น กระบวนการสมัครสมาชิกผู้ใช้มักจำเป็นแต่ไม่ใช่ feature หลัก ให้ model เป็น event หยาบๆ ตัวเดียว
UserRegisteredแล้วไปต่อ ทุ่มแรงไปที่ event ที่สำคัญกว่า
หากคิดว่าได้ Domain Event สำคัญครบหมดแล้ว อาจถึงเวลาพักแล้วกลับมาทำ session ต่อภายหลัง การกลับมาที่พื้นที่ model ในวันถัดไปจะทำให้พบแนวคิดที่ขาดหายและได้กลั่นหรือทิ้ง event ผิวเผินที่เคยคิดว่าสำคัญ เมื่อระบุ Domain Event สำคัญส่วนใหญ่ได้แล้วจึงไปขั้นถัดไป
[ProductCreated] → [ReleaseScheduled] → [SprintScheduled] → [BacklogItemPlanned] → [BacklogItemCommitted] เวลา (Time) ──────────────────────────────────────────────►ขั้นที่ 2 — สร้าง Command ที่ก่อให้เกิด Domain Event (โน้ตสีฟ้าอ่อน)
หัวข้อที่มีชื่อว่า “ขั้นที่ 2 — สร้าง Command ที่ก่อให้เกิด Domain Event (โน้ตสีฟ้าอ่อน)”สร้าง Command ที่เป็นต้นเหตุของ Domain Event แต่ละตัว บางครั้ง Domain Event มาจากระบบอื่นแล้วไหลเข้ามา แต่บ่อยครั้ง Command คือผลของ “ท่าทาง” (gesture) ของผู้ใช้ และเมื่อ Command ถูกดำเนินการ มันจะก่อให้เกิด Domain Event ตั้งชื่อ Command เป็น รูปคำสั่ง (imperative) เช่น CreateProduct และ CommitBacklogItem แนวทาง:
- เขียนชื่อ Command บนโน้ต ฟ้าอ่อน เช่น Domain Event ชื่อ
BacklogItemCommittedมี Command คู่กันคือCommitBacklogItem - วางโน้ต Command ไว้ ทางซ้ายของ Domain Event ที่มันก่อให้เกิด จับคู่กันเป็น Command/Event เป็นคู่ๆ ไป (จำไว้ว่าบาง Domain Event เกิดเพราะถึงกำหนดเวลา จึงอาจไม่มี Command ที่ก่อมันโดยตรง)
- หากมี บทบาทผู้ใช้ (user role) ที่เจาะจงและสำคัญที่จะระบุ ให้ติดโน้ต เหลืองเล็กๆ ที่มุมล่างซ้ายของ Command พร้อมรูปคนกับชื่อบทบาท เช่น “Product Owner”
- บางครั้ง Command ก่อให้เกิด Process ให้จับลงโน้ตม่วงลิลลี่แล้วลากเส้นมีหัวลูกศรเหมือนเดิม Process นั้นจะก่อให้เกิด Command และ Domain Event ตามมาอีก
- เคลื่อนจากซ้ายไปขวาตามลำดับเวลาเหมือนตอนสร้าง Domain Event
การสร้าง Command อาจทำให้นึกถึง Domain Event ที่ยังไม่เคยเห็นมาก่อน (เช่นตอนพบ Process สีลิลลี่) อย่าเพิกเฉย ให้วางมันลงพร้อม Command ที่คู่กัน และอาจพบว่ามี Command เพียงตัวเดียวที่ก่อให้เกิด Domain Event หลายตัว — ไม่เป็นไร model Command ตัวเดียวแล้ววางไว้ทางซ้ายของ Domain Event หลายตัวที่มันก่อ
ขั้นที่ 3 — ผูก Entity/Aggregate ที่ Command ทำงานบนนั้น (โน้ตสีเหลืองอ่อน)
หัวข้อที่มีชื่อว่า “ขั้นที่ 3 — ผูก Entity/Aggregate ที่ Command ทำงานบนนั้น (โน้ตสีเหลืองอ่อน)”ผูก EntityEntityอ็อบเจ็กต์ที่มี “ตัวตน” (identity) ต่อเนื่องตามเวลา แม้ค่าภายในเปลี่ยน ก็ยังเป็นสิ่งเดิม เช่น ลูกค้า, คำสั่งซื้อ — แยกแยะด้วย id ไม่ใช่ด้วยค่าTactical Design/AggregateAggregateกลุ่มของ Entity และ Value Object ที่ถูกมองเป็นหนึ่งหน่วยเดียวเพื่อรักษาความถูกต้องของข้อมูล มีขอบเขตชัดเจน และเป็นหน่วยของ transactionTactical Design ที่เป็นตัวรับการดำเนินการของ Command และเป็นตัวปล่อย Domain Event ออกมา นี่คือ “ตัวถือข้อมูล” ที่ Command ถูกดำเนินการและ Domain Event ถูกปล่อย น่าสนใจที่แผนภาพ Entity-relationship มักเป็นขั้นแรกที่คนไอทียุคนี้นิยม แต่นั่นเป็นความผิดพลาดใหญ่ที่จะเริ่มตรงนั้น เพราะคนธุรกิจไม่เข้าใจมันดีและจะทำให้บทสนทนาสะดุด ใน EventStorming ขั้นนี้จึงถูกลดไปอยู่อันดับสาม เพราะเราเน้น กระบวนการทางธุรกิจ มากกว่าข้อมูล แต่ถึงจุดนี้เราจำเป็นต้องคิดเรื่องข้อมูลแล้ว แนวทาง:
- ถ้าคนธุรกิจไม่ชอบคำว่า Aggregate หรือมันทำให้สับสน ก็ใช้คำอื่นได้ เช่น Entity หรือเรียกแค่ “Data” สิ่งสำคัญคือโน้ตสื่อแนวคิดที่มันแทนได้ชัดเจน ใช้โน้ต เหลืองอ่อน สำหรับ Aggregate ทุกตัว เขียนชื่อเป็นคำนาม เช่น
ProductหรือBacklogItem - วางโน้ต Aggregate ไว้ ด้านหลังและเหนือขึ้นเล็กน้อย จากคู่ Command/Event เพื่อให้อ่านชื่อคำนามได้ ส่วนคู่ Command/Event ติดอยู่ส่วนล่างของโน้ต Aggregate เพื่อแสดงว่าผูกกัน
- เมื่อไล่ไปตามไทม์ไลน์ จะพบว่า Aggregate ตัวเดิมถูกใช้ซ้ำๆ อย่าจัดเรียงไทม์ไลน์ใหม่ เพื่อยุบทุกคู่ Command/Event มาไว้ใต้ Aggregate ใบเดียว แต่ให้สร้างคำนาม Aggregate เดิมบนโน้ตหลายใบแล้ววางซ้ำตรงที่คู่ Command/Event เกิด เพราะหัวใจคือการ model กระบวนการทางธุรกิจที่เกิดตามเวลา
- ขณะคิดเรื่องข้อมูล อาจค้นพบ Domain Event ใหม่ อย่าเพิกเฉย ให้วางมันลงพร้อม Command และ Aggregate ที่คู่กัน และอาจพบว่าบาง Aggregate ซับซ้อนเกินไปจนต้องแตกเป็น Process (โน้ตลิลลี่) อย่ามองข้ามโอกาสเหล่านี้
แกนของ EventStorming คือสามสี: ฟ้า = Command (สิ่งที่ตั้งใจให้เกิด) → เหลือง = Aggregate (ตัวที่บังคับใช้กฎ) → ส้ม = Domain Event (สิ่งที่เกิดขึ้นแล้ว) เรียงทั้งหมดตามเวลาจากซ้ายไปขวา แล้วเพิ่ม ม่วงลิลลี่ = Process, ม่วง/แดง = จุดปัญหา, ชมพู = Bounded Context, เขียว = View และ เหลืองเล็ก = บทบาทผู้ใช้ เป็นชั้นเสริม
ทำขั้นนี้เสร็จก็เข้าใกล้ขั้นเสริมที่จะทำหรือไม่ทำก็ได้ และเข้าใจด้วยว่าหากใช้ Event SourcingEvent Sourcingเก็บทุกการเปลี่ยนสถานะเป็น event ที่เปลี่ยนไม่ได้ แล้วสร้างสถานะปัจจุบันด้วยการเล่น event ซ้ำ มัก “ต้องใช้คู่กับ CQRS” (Greg Young) มี event stream ต่อ1 AggregateArchitecture อยู่ ก็เดินทางมาไกลในการเข้าใจวิธี implement Core Domain แล้ว เพราะ EventStorming และ Event Sourcing ทับซ้อนกันมาก แน่นอนว่ายิ่ง storming ใกล้ภาพรวม ก็ยิ่งไกลจากการ implement จริง แต่เทคนิคเดียวกันนี้ใช้ไปถึงระดับ design-level ได้ ในประสบการณ์ของ Vernon ทีมมักสลับเข้าออกระหว่าง big-picture กับ design-level ภายใน session เดียวกัน
ขั้นที่ 4 — วาดขอบเขตและเส้นแสดงการไหล (โน้ตสีชมพู)
หัวข้อที่มีชื่อว่า “ขั้นที่ 4 — วาดขอบเขตและเส้นแสดงการไหล (โน้ตสีชมพู)”วาดขอบเขตและเส้นที่มีลูกศรเพื่อแสดง “การไหล” บนพื้นที่ model เมื่อมาถึงจุดนี้มักพบว่ามีหลาย model ทำงานอยู่ และมี Domain Event ไหลข้ามไปมาระหว่าง model วิธีจัดการ:
- โดยสรุป มักพบขอบเขตภายใต้เงื่อนไขเหล่านี้: การแบ่งแผนก, เมื่อคนธุรกิจต่างนิยามคำเดียวกันขัดแย้งกัน, หรือเมื่อแนวคิดสำคัญแต่ไม่ใช่ส่วนหนึ่งของ Core Domain จริงๆ
- ใช้ปากกาเมจิกหัวดำวาดบนกระดาษ แสดงขอบเขตของ context และขอบเขตอื่น ใช้ เส้นทึบ สำหรับ Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design และ เส้นประ สำหรับ Subdomain (การวาดบนกระดาษถาวร จึงควรมั่นใจในระดับรายละเอียดนี้ก่อน หากยังไม่มั่นใจให้ใช้โน้ตชมพูมาร์กพื้นที่คร่าวๆ ก่อน)
- วางโน้ต ชมพู ไว้ในแต่ละขอบเขตแล้วเขียนชื่อที่ใช้กับขอบเขตนั้น เพื่อตั้งชื่อ Bounded Context
- ลากเส้นมีหัวลูกศรเพื่อแสดง ทิศทางการไหลของ Domain Event ระหว่าง Bounded Context นี่เป็นวิธีที่สื่อว่า Domain Event บางตัวมาถึงระบบเราโดยไม่ได้เกิดจาก Command ในระบบเราเอง
รายละเอียดอื่นของขั้นนี้น่าจะเข้าใจได้เองโดยสัญชาตญาณ — แค่ใช้ขอบเขตและเส้นในการสื่อสาร
graph LR
subgraph BC1["Bounded Context A (ชมพู)"]
direction TB
C1["Command A1 (ฟ้า)"] --> AG1["Aggregate A (เหลือง)"]
AG1 --> E1["Event A1 (ส้ม)"]
end
subgraph BC2["Bounded Context B (ชมพู)"]
direction TB
AG2["Aggregate B (เหลือง)"] --> E2["Event B1 (ส้ม)"]
end
E1 -->|"Domain Event ไหลข้าม context"| AG2
ขั้นที่ 5 — ระบุ View และบทบาทผู้ใช้ที่สำคัญ (โน้ตสีเขียว/เหลือง)
หัวข้อที่มีชื่อว่า “ขั้นที่ 5 — ระบุ View และบทบาทผู้ใช้ที่สำคัญ (โน้ตสีเขียว/เหลือง)”ระบุ View ต่างๆ ที่ผู้ใช้จำเป็นต้องใช้เพื่อทำงานให้สำเร็จ และ บทบาท สำคัญของผู้ใช้แต่ละกลุ่ม
- ไม่จำเป็นต้องแสดงทุก View ที่ UI จะมี (หรือไม่แสดงเลยก็ได้) หากตัดสินใจแสดง ควรเป็น View ที่สำคัญและต้องการความใส่ใจพิเศษในการสร้าง แทนด้วยโน้ต เขียว บนพื้นที่ model จะวาด mockup หรือ wireframe คร่าวๆ ของ View ที่สำคัญที่สุดด้วยก็ได้ถ้าช่วยให้เข้าใจ
- ใช้โน้ต เหลืองสด แทนบทบาทผู้ใช้สำคัญ แสดงเฉพาะเมื่อต้องสื่อสารบางอย่างที่มีนัยสำคัญเกี่ยวกับการโต้ตอบของผู้ใช้กับระบบ หรือสิ่งที่ระบบทำให้บทบาทนั้นโดยเฉพาะ
เป็นไปได้ว่าขั้นที่สี่และห้าคือ “ของเสริม” ทั้งหมดที่จำเป็นต้องผนวกเข้ากับเวิร์กช็อป EventStorming ของเรา
ลองพายุกระบวนการ “สั่งซื้อ” ออกมา: Command PlaceOrder (ฟ้า) → Aggregate Order (เหลือง) → Domain Event OrderPlaced (ส้ม) จากนั้น OrderPlaced ลากเส้นไหลข้ามไปยัง Bounded Context “คลังสินค้า” (ชมพู) ที่จะเกิด Process จัดเตรียมสินค้าต่อ — ทั้งหมดเรียงตามเวลาจากซ้ายไปขวา และทุกคนในห้องช่วยกันตั้งชื่อให้เป็นภาษากลาง
เครื่องมือเสริมอื่นๆ (Other Tools)
หัวข้อที่มีชื่อว่า “เครื่องมือเสริมอื่นๆ (Other Tools)”ทั้งหมดนี้ไม่ได้ห้ามเราทดลอง เช่น วาดสิ่งอื่นเพิ่มบนพื้นที่ model หรือลองขั้นตอนการ model อื่นใน session EventStorming จำไว้ว่านี่คือเรื่องของการเรียนรู้และสื่อสาร design ใช้เครื่องมือไหนก็ได้ในฐานะทีมที่แน่นแฟ้น เพียงระวังอย่าให้มีพิธีรีตอง (ceremony) มากเกินไป เพราะนั่นแพง ไอเดียเสริมอื่นๆ:
- เพิ่ม executable specification ระดับสูง แบบ given/when/then (หรือที่เรียกว่า acceptance test) อ่านเพิ่มได้ในหนังสือ Specification by Example ของ Gojko Adzic เพียงระวังอย่าหมกมุ่นจนมันกลืนทุกอย่างและสำคัญเหนือ domain model จริงๆ Vernon ประเมินว่าการใช้และดูแล executable specification กินเวลาและแรงเพิ่มราว 15% ถึง 25% เทียบกับการใช้ unit test ทั่วไป และง่ายที่จะติดกับการคอยรักษา spec ให้สอดคล้องกับทิศทางธุรกิจที่เปลี่ยนไปต่อเนื่อง
- ลอง Impact Mapping (เทคนิคของ Gojko Adzic เช่นกัน) เพื่อมั่นใจว่าซอฟต์แวร์ที่ออกแบบเป็น Core Domain จริง ไม่ใช่ model ที่สำคัญน้อยกว่า
- ลอง User Story Mapping ของ Jeff Patton เพื่อโฟกัสไปที่ Core Domain และเข้าใจว่าควรลงทุนกับ feature ใด
เครื่องมือเสริมสามตัวข้างต้นทับซ้อนกับปรัชญา DDD อย่างมาก และเหมาะจะนำมาใช้ใน project DDD ใดๆ ทั้งหมดออกแบบมาเพื่อ project ที่เร่งความเร็วสูง มีพิธีรีตองต่ำ และใช้งานได้ในราคาถูกมาก
บริหาร DDD บน project Agile
หัวข้อที่มีชื่อว่า “บริหาร DDD บน project Agile”มีกระแสที่เรียกว่า No Estimates ซึ่งปฏิเสธการประมาณการแบบเดิมอย่าง story point หรือ task hour โดยโฟกัสที่การส่งมอบ “คุณค่า” เหนือการคุมต้นทุน และไม่ประมาณงานที่น่าจะใช้เวลาแค่ไม่กี่เดือน Vernon ไม่ปัดตกแนวทางนี้ แต่ ณ เวลาที่เขียนหนังสือ ลูกค้าที่เขาทำงานด้วยยังถูกบังคับให้ส่งประมาณการและ timebox งานอยู่ดี หาก No Estimates เวิร์กกับสถานการณ์ของเรา ก็ใช้ได้เลย
นอกจากนี้บางคนในวงการ DDD ได้นิยามกระบวนการของตัวเองสำหรับการใช้ DDD ซึ่งอาจได้ผลเมื่อทีมยอมรับ แต่ขอ buy-in จากองค์กรที่ลงทุนกับ framework Agile อย่าง Scrum ไปแล้วได้ยากกว่า
ช่วงหลัง Scrum ถูกวิจารณ์หนัก Vernon ไม่เลือกข้าง แต่ยอมรับตรงๆ ว่าบ่อยครั้ง (หรือส่วนใหญ่) Scrum ถูกใช้ผิดวิธี เขาเคยพูดถึงแนวโน้มที่ทีมจะ “ออกแบบ” ด้วยสิ่งที่เขาเรียกว่า task-board shuffle (การสับ Post-it บนบอร์ด) ซึ่งไม่ใช่วิธีที่ Scrum ตั้งใจให้ใช้ และขอย้ำอีกครั้งว่า การได้มาซึ่งความรู้ (knowledge acquisition) เป็นทั้งหลักการของ Scrum และเป้าหมายสำคัญของ DDD แต่กลับถูกละเลยเพื่อแลกกับการส่งมอบแบบไม่หยุดพัก กระนั้น Scrum ก็ยังถูกใช้อย่างกว้างขวางและคงไม่หายไปเร็วนัก
ดังนั้นบทนี้จะแสดงวิธีทำให้ DDD ทำงานใน project ที่ใช้ Scrum เทคนิคเหล่านี้ใช้ได้กับ Agile แนวอื่นเช่น Kanban เช่นกัน — ไม่มีอะไรผูกขาดกับ Scrum แม้คำแนะนำบางส่วนจะพูดในเชิง Scrum ที่ใดใช้คำว่า task หรือ task board ก็เข้ากันได้กับ Agile ทั่วไปและ Kanban ที่ใดใช้คำว่า sprint ก็เทียบได้กับ iteration (Agile ทั่วไป) และ WIP (work in progress; อ้างถึง Kanban) คำแนะนำส่วนใหญ่จะเกี่ยวกับการ model domain การเรียนรู้ การทดลอง และการออกแบบด้วย DDD ส่วนแนวทาง Scrum/Kanban ทั่วไปต้องหาอ่านที่อื่น
First Things First — เรื่องสำคัญต้องมาก่อน
หัวข้อที่มีชื่อว่า “First Things First — เรื่องสำคัญต้องมาก่อน”หนึ่งในวิธีที่สำคัญที่สุดในการใช้ DDD ให้สำเร็จคือ จ้างคนเก่ง ไม่มีอะไรทดแทนคนเก่งได้ โดยเฉพาะนักพัฒนาที่เหนือค่าเฉลี่ย DDD เป็นปรัชญาและเทคนิคขั้นสูง จึงต้องการนักพัฒนาที่เก่งกว่าค่าเฉลี่ย (หรือเก่งมาก) มาใช้งาน อย่าประเมินความสำคัญของการจ้างคนที่ใช่ มีทักษะที่ถูกต้อง และมีแรงขับในตัวเองต่ำเกินไป
ใช้การวิเคราะห์ SWOT (Use SWOT Analysis)
หัวข้อที่มีชื่อว่า “ใช้การวิเคราะห์ SWOT (Use SWOT Analysis)”SWOT AnalysisSWOT Analysisการวิเคราะห์จุดแข็ง (Strengths), จุดอ่อน (Weaknesses), โอกาส (Opportunities) และอุปสรรค (Threats) เพื่อประเมินทิศทางของ project DDD อย่างรอบด้านProcess ย่อมาจาก Strengths (จุดแข็ง), Weaknesses (จุดอ่อน), Opportunities (โอกาส) และ Threats (อุปสรรค) เป็นวิธีคิดเกี่ยวกับ project ในมุมที่เจาะจง เพื่อเก็บเกี่ยวความรู้ให้มากที่สุดเร็วที่สุด สิ่งที่มองหาใน project:
- Strengths (จุดแข็ง): ลักษณะของธุรกิจหรือ project ที่ให้ความได้เปรียบเหนือผู้อื่น — “สิ่งที่เรามีอยู่”
- Weaknesses (จุดอ่อน): ลักษณะที่ทำให้ธุรกิจหรือ project เสียเปรียบเทียบกับผู้อื่น — “สิ่งที่ปรับปรุงได้”
- Opportunities (โอกาส): องค์ประกอบที่ project ใช้ให้เป็นประโยชน์ได้ — “สิ่งที่ทุ่มพลังลงไปได้”
- Threats (อุปสรรค): องค์ประกอบในสภาพแวดล้อมที่อาจสร้างปัญหาให้ธุรกิจหรือ project — “อุปสรรคที่ต้องข้ามให้ได้”
เมื่อใดก็ตามบน project Scrum หรือ Agile อื่น ใช้ SWOT เพื่อประเมินสถานการณ์ปัจจุบันได้เลย:
- วาด เมทริกซ์ใหญ่สี่ช่อง
- กลับไปที่กระดาษโน้ต เลือกสีต่างกันสำหรับแต่ละช่องของ SWOT
- ระบุ Strengths, Weaknesses, Opportunities และ Threats ของ project
- เขียนลงโน้ตแล้ววางในช่องที่เหมาะสมของเมทริกซ์
- ใช้คุณลักษณะ SWOT เหล่านี้ (โดยเฉพาะคิดถึง domain model) เพื่อ วางแผนว่าจะทำอะไรกับมัน ขั้นตอนถัดไปในการส่งเสริมจุดดีและบรรเทาจุดที่มีปัญหาอาจเป็นตัวชี้เป็นชี้ตายความสำเร็จ
เรามีโอกาสเอา action เหล่านี้ไปวางบน task board ตอนวางแผน project (จะกล่าวต่อไป)
┌─────────────────────────────┬─────────────────────────────┐│ Strengths (จุดแข็ง) │ Weaknesses (จุดอ่อน) ││ สิ่งที่เรามีอยู่ │ สิ่งที่ปรับปรุงได้ │├─────────────────────────────┼─────────────────────────────┤│ Opportunities (โอกาส) │ Threats (อุปสรรค) ││ สิ่งที่ทุ่มพลังลงไปได้ │ อุปสรรคที่ต้องข้ามให้ได้ │└─────────────────────────────┴─────────────────────────────┘Modeling Spike และ Modeling Debt
หัวข้อที่มีชื่อว่า “Modeling Spike และ Modeling Debt”แปลกใจไหมว่า project DDD ก็มี Modeling Spike และ Modeling Debt ให้จ่ายได้?
หนึ่งในสิ่งที่ดีที่สุดที่ทำได้ตอนเริ่ม project คือใช้ EventStorming การทดลอง model ทำนองนี้นับเป็น Modeling SpikeModeling Spikeการจัดสรรเวลา timeboxed ให้ทีมสำรวจและทดลองสร้าง model โดยไม่ต้องส่งมอบ production code เพื่อลดความเสี่ยงและเรียนรู้ domain ก่อลงมือทำจริงProcess เราต้อง “ซื้อ” ความรู้เกี่ยวกับ Scrum product ของเรา และบางครั้งราคาที่จ่ายคือ spike และ spike ช่วงเริ่ม project แทบจะแน่นอน กระนั้น EventStorming ก็ช่วยลดต้นทุนการลงทุนที่จำเป็นนี้ได้มาก
แน่นอนว่าเราคาดหวังให้ model domain สมบูรณ์แบบตั้งแต่เริ่มไม่ได้ แม้จะมองว่าการเริ่ม project คือ Modeling Spike ที่มีคุณค่าก็ตาม แม้แต่ตอนใช้ EventStorming ก็จะยังไม่สมบูรณ์แบบ เพราะธุรกิจและความเข้าใจของเราต่อมันเปลี่ยนไปตามเวลา และ domain model ก็เปลี่ยนตาม
ยิ่งกว่านั้น ถ้าตั้งใจ timebox งาน model เป็น task บน task board ก็ให้คาดไว้เลยว่าจะเกิด Modeling Debt ในแต่ละ sprint (หรือ iteration หรือ WIP) เพราะเราจะไม่มีเวลาทำทุก task model ให้สมบูรณ์ได้ในกรอบเวลาที่จำกัด เช่น เริ่ม design ไปแล้วเพิ่งพบหลังทดลองว่ามันไม่เข้ากับความต้องการธุรกิจอย่างที่คาด แต่ข้อจำกัดเวลาก็บังคับให้ต้องเดินหน้า
สิ่งที่แย่ที่สุดที่ทำได้ตอนนี้คือ ลืมทุกอย่างที่เรียนรู้ จากความพยายาม model ที่เรียกร้อง design ที่ดีกว่า แทนที่จะทำเช่นนั้น ให้จดบันทึกไว้ว่าเรื่องนี้ต้องเข้า sprint ถัดไป (หรือ iteration, WIP) นำเข้าที่ประชุม retrospective แล้วเสนอเป็น task ใหม่ในการวางแผน sprint ถัดไป (หรือเพิ่มเข้าคิว Kanban) — ใน Kanban ทำ retrospective ได้ทุกวัน จึงไม่ต้องรอนานในการเสนอความจำเป็นปรับปรุง model
Modeling Debt ไม่ใช่ความล้มเหลว แต่เป็นผลตามธรรมชาติของการ timebox สิ่งที่ทำลายคุณค่าจริงๆ คือการ “ลืม” บทเรียนจากการทดลองที่ชี้ว่าควรมี design ที่ดีกว่า จงบันทึกหนี้ก้อนนั้นไว้และทยอยจ่ายในอนาคต (ในอุดมคติคืออนาคตอันใกล้)
ระบุ Task และประมาณการความพยายาม (Identifying Tasks and Estimating Effort)
หัวข้อที่มีชื่อว่า “ระบุ Task และประมาณการความพยายาม (Identifying Tasks and Estimating Effort)”EventStorming ใช้ได้ทุกเวลา ไม่ใช่แค่ตอนเริ่ม project ขณะทำ session เราจะสร้าง artifact จำนวนหนึ่งออกมาอย่างเป็นธรรมชาติ — Domain Event, Command และ Aggregate แต่ละตัวที่ storm ออกมาบน model กระดาษ ใช้เป็นหน่วยประมาณการ (estimation unit) ได้ ทำได้อย่างไร?
วิธีประมาณการที่ง่ายและแม่นที่สุดวิธีหนึ่งคือ แนวทางอิง metric (metrics-based) สร้างตารางที่มีหน่วยประมาณการสำหรับ component แต่ละชนิดที่ต้อง implement วิธีนี้ตัด “การเดา” ออก แล้วใส่หลักการเชิงวิทยาศาสตร์เข้าไปในกระบวนการ:
| Component Type | Easy (ชั่วโมง) | Moderate (ชั่วโมง) | Complex (ชั่วโมง) |
|---|---|---|---|
| Domain Event | 0.1 | 0.2 | 0.3 |
| Command | 0.1 | 0.2 | 0.3 |
| Aggregate | 1 | 2 | 4 |
| … | … | … | … |
ตารางทำงานดังนี้:
- สร้าง column Component Type อธิบายชนิดของ component ที่นิยามหน่วยประมาณการ
- สร้างอีก3 column: Easy, Moderate, Complex สะท้อนหน่วยประมาณการเป็นชั่วโมงหรือเศษส่วนชั่วโมงของ component แต่ละชนิด
- สร้างหนึ่งแถวต่อ component แต่ละชนิดในสถาปัตยกรรม (ในตารางมี Domain Event, Command, Aggregate แต่อย่าจำกัดแค่นี้ — สร้างแถวสำหรับ UI component, service, persistence, ตัว serialize/deserialize ของ Domain Event และอื่นๆ ได้ทุกชนิด หากปกติสร้าง serializer/deserializer ควบคู่กับ Domain Event ก็กำหนดค่าประมาณการของ Domain Event ให้ครอบคลุมการสร้างทั้งหมดนั้นไปด้วย)
- กรอกจำนวนชั่วโมงหรือเศษส่วนสำหรับแต่ละระดับความยาก: easy, moderate, complex ค่าประมาณนี้รวมทั้งเวลา implement และอาจรวมเวลาออกแบบและทดสอบเพิ่มเติม จงทำให้แม่นและสมจริง
- เมื่อรู้ task ของ backlog item (WIP) ที่จะทำ ให้ดึง metric สำหรับแต่ละ task มาระบุให้ชัด อาจใช้สเปรดชีตช่วย
- รวมหน่วยประมาณการของทุก component ใน sprint ปัจจุบัน (iteration หรือ WIP) เข้าด้วยกัน นั่นคือประมาณการรวม
ขณะรันแต่ละ sprint (iteration หรือ WIP) ให้ ปรับจูน metric ให้สะท้อนชั่วโมงที่ใช้จริง หากใช้ Scrum และเริ่มเกลียดการประมาณเป็นชั่วโมง ให้เข้าใจว่าวิธีนี้ผ่อนปรนและแม่นกว่ามาก ยิ่งเรียนรู้จังหวะของทีม ก็ยิ่งจูน metric ให้แม่นขึ้น อาจต้องใช้หลาย sprint กว่าจะลงตัว และเมื่อทีมเก่งและมีประสบการณ์ขึ้น มักจะปรับตัวเลขลงหรือใช้ column Easy/Moderate ได้บ่อยขึ้น
หากใช้ Kanban และคิดว่าการประมาณการนั้นไร้สาระและไม่จำเป็นเลย ลองถามตัวเองว่า “แล้วเราจะรู้ได้อย่างไรว่าควรกำหนด WIP เท่าไรเพื่อจำกัดคิวงานให้ถูกต้อง?” ไม่ว่าจะคิดอย่างไร เราก็กำลังประมาณการความพยายามและหวังว่ามันถูกอยู่ดี — ทำไมไม่เติมหลักการเชิงวิทยาศาสตร์เข้าไปด้วยวิธีประมาณการที่ง่ายและแม่นนี้?
มีโปรแกรมองค์กรขนาดใหญ่หนึ่งที่ต้องประมาณการ project ใหญ่และซับซ้อน มีสองทีมรับงานนี้ ทีมแรกเป็นที่ปรึกษาค่าตัวสูงที่เคยทำงานประมาณการให้บริษัท Fortune 500 มีดีกรีปริญญาเอกและอุปกรณ์ครบมือ ส่วนทีมที่สองเป็นสถาปนิกและนักพัฒนาที่ใช้กระบวนการประมาณการแบบ metrics-based นี้ project อยู่ในระดับ 20 ล้านดอลลาร์ และเมื่อประมาณการของทั้งสองทีมออกมา กลับ ต่างกันเพียงราว 200,000 ดอลลาร์ (โดยทีมเทคนิคประเมินต่ำกว่าเล็กน้อย) ไม่เลวเลยสำหรับสายเทคนิค คาดหวังความแม่นในกรอบ 20% สำหรับประมาณการระยะยาว และแม่นกว่านั้นมากสำหรับระยะสั้นอย่าง sprint, iteration และคิว WIP
To Do In Progress Done───────────────────── ───────────────────── ─────────────────────AdSpot Aggregate (1) Appointment Aggregate (2) AdCredits Aggregate (3)AdSpot Commands (1) Appointment Events (2) AdCredits Commands (1)AdSpot Events (1.5) ServiceShop Aggregate (2) AdCredits Events (1)Payment (0.5)Timeboxed Modeling — model ภายใต้กรอบเวลา
หัวข้อที่มีชื่อว่า “Timeboxed Modeling — model ภายใต้กรอบเวลา”เมื่อมีประมาณการของ component แต่ละชนิดแล้ว ก็สร้าง task โดยอิงจาก component เหล่านั้นได้โดยตรง อาจเก็บแต่ละ component เป็น task เดียวพร้อมจำนวนชั่วโมง หรือแตก task ให้ละเอียดขึ้นก็ได้ แต่ Vernon แนะนำให้ระวังการแตก task ละเอียดเกินไปจนทำให้ task board ซับซ้อนเกินจำเป็น ดังที่แสดงก่อนหน้า อาจดีที่สุดที่จะ รวม Command และ Domain Event ทั้งหมดของ Aggregate เดียว ไว้เป็น task เดียว
graph LR S1["Scenario #1 (เขียว)"] <--> TA["Test Aggregate A (ขาว)"] S2["Scenario #2 (เขียว)"] <--> TA S3["Scenario #3 (เขียว)"] <--> TA2["Test Aggregate A (ขาว)"] TA <--> AGA["Aggregate A (เหลือง)"] TA2 <--> AGA AGA --- CA["Command A1 (ฟ้า)"] AGA --- EA["Event A1 (ส้ม)"] AGA --> AGB["Aggregate B (เหลือง)"]
How to Implement — ลงมือทำอย่างไร
หัวข้อที่มีชื่อว่า “How to Implement — ลงมือทำอย่างไร”แม้จะมี artifact ที่ EventStorming ระบุไว้ ก็ไม่จำเป็นว่าจะมีความรู้ครบทุกอย่างที่ต้องใช้ทำงานบน domain scenario, story หรือ use case หนึ่งๆ ถ้าต้องการมากกว่านั้น ให้รวมเวลาสำหรับ การได้มาซึ่งความรู้เพิ่มเติม ไว้ในประมาณการด้วย แต่เวลาสำหรับทำอะไร? จำได้ไหมว่าก่อนหน้านี้มีการพูดถึงการสร้าง concrete scenario รอบๆ domain model — นี่คือหนึ่งในวิธีที่ดีที่สุดในการได้มาซึ่งความรู้เกี่ยวกับ Core Domain เกินกว่าที่ EventStorming ให้ได้ Concrete scenario และ EventStorming คือสองเครื่องมือที่ควรใช้ควบคู่กัน วิธีทำงาน:
- ทำ session EventStorming สั้นๆ สักหนึ่งชั่วโมง แทบแน่นอนว่าจะพบว่าต้องพัฒนา concrete scenario เพิ่มรอบๆ สิ่งที่เพิ่งค้นพบ
- จับคู่กับ ผู้เชี่ยวชาญธุรกิจDomain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design เพื่อหารือ scenario รูปธรรมหนึ่งหรือมากกว่าที่ต้องกลั่น เพื่อระบุว่า model จะถูกใช้อย่างไร เป้าหมายไม่ใช่แค่เขียนขั้นตอน แต่เพื่อระบุ องค์ประกอบของ domain model จริงๆ (เช่น อ็อบเจ็กต์) ว่ามันทำงานร่วมกันอย่างไร และโต้ตอบกับผู้ใช้อย่างไร
- สร้างชุด acceptance test (หรือ executable specification) ที่ออกกำลังแต่ละ scenario
- สร้าง component เพื่อให้ test/specification รันได้ ทำซ้ำ (สั้นและเร็ว) ขณะกลั่น test/specification และ component จนกว่ามันจะทำในสิ่งที่ผู้เชี่ยวชาญธุรกิจคาดหวัง
- มีโอกาสสูงที่การทำซ้ำ (สั้นและเร็ว) จะทำให้เราพิจารณา scenario อื่น สร้าง test/specification เพิ่ม และกลั่นของเดิมพร้อมสร้าง component ใหม่
ทำเช่นนี้ต่อไปจนได้ความรู้ที่จำเป็นครบเพื่อบรรลุเป้าหมายธุรกิจที่จำกัดไว้ หรือจนกว่า timebox จะหมด หากยังไปไม่ถึงจุดที่ต้องการ ให้บันทึก Modeling Debt ไว้แก้ในอนาคต (ในอุดมคติคืออนาคตอันใกล้)
ตัวอย่างของ scenario แบบ given/when/then ที่กลายเป็น executable specification และ test มีรูปร่างประมาณนี้:
Scenario: The product owner commits a backlog item to a sprint Given a backlog item that is scheduled for release And the product owner of the backlog item And a sprint for commitment And a quorum of team approval for commitment When the product owner commits the backlog item to the sprint Then the backlog item is committed to the sprint And the backlog item committed event is created/* The product owner commits a backlog item to a sprint. The backlog item may be committed only if it is already scheduled for release, and if a quorum of team members have approved commitment. When the commitment completes, notify the sprint to which it is now committed.*/
[Test]public void ShouldCommitBacklogItemToSprint(){ // Given var backlogItem = BacklogItemScheduledForRelease(); var productOwner = ProductOwnerOf(backlogItem); var sprint = SprintForCommitment(); var quorum = QuorumOfTeamApproval(backlogItem, sprint);
// When backlogItem.CommitTo(sprint, productOwner, quorum);
// Then Assert.IsTrue(backlogItem.IsCommitted());
var backlogItemCommitted = backlogItem.Events.OfType<BacklogItemCommitted>().SingleOrDefault();
Assert.IsNotNull(backlogItemCommitted);}การทำงานร่วมกับ Domain Expert (Interacting with Domain Experts)
หัวข้อที่มีชื่อว่า “การทำงานร่วมกับ Domain Expert (Interacting with Domain Experts)”หนึ่งในความท้าทายใหญ่ของการใช้ DDD คือ การได้เวลากับ ผู้เชี่ยวชาญธุรกิจDomain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design โดยไม่มากเกินไป หลายครั้งผู้เชี่ยวชาญธุรกิจมีภาระอื่นมหาศาล ทั้งประชุมหลายชั่วโมงและอาจต้องเดินทาง การหาเวลาให้พอจึงยาก เราจึงต้องทำให้ทุกนาทีที่ใช้ “คุ้มค่า” และจำกัดเฉพาะที่จำเป็น หาก session model ไม่สนุกและไม่มีประสิทธิภาพ มีโอกาสสูงที่จะเสียความช่วยเหลือไปในจังหวะที่ผิดที่สุด แต่ถ้าพวกเขาเห็นว่ามันมีคุณค่า เปิดหูเปิดตา และคุ้มค่า ก็จะเกิด partnership ที่แข็งแรงอย่างที่ต้องการ
คำถามแรกที่ต้องตอบคือ “เมื่อไรที่ต้องการเวลากับผู้เชี่ยวชาญธุรกิจ? task ใดที่ต้องให้เขาช่วย?”
- รวมผู้เชี่ยวชาญธุรกิจในกิจกรรม EventStorming เสมอ นักพัฒนาจะมีคำถามมากมาย และผู้เชี่ยวชาญธุรกิจมีคำตอบ ต้องอยู่ใน session EventStorming ด้วยกัน
- ต้องการ input จากผู้เชี่ยวชาญธุรกิจในการหารือและสร้าง model scenario
- ต้องการผู้เชี่ยวชาญธุรกิจมา รีวิว test เพื่อยืนยันความถูกต้องของ model โดยสมมติว่านักพัฒนาได้ตั้งใจยึด ภาษากลางUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงใน codeStrategic Design และใช้ข้อมูลทดสอบที่มีคุณภาพและสมจริงแล้ว
- ต้องการผู้เชี่ยวชาญธุรกิจมา กลั่นภาษากลาง ทั้งชื่อ Aggregate, Command และ Domain Event ซึ่งทั้งทีมร่วมกันกำหนด ความกำกวมถูกแก้ผ่านการรีวิว ตั้งคำถาม และอภิปราย แม้กระนั้น session EventStorming ควรแก้คำถามเกี่ยวกับภาษากลางไปแล้วเป็นส่วนใหญ่
แล้วต้องใช้เวลาจากผู้เชี่ยวชาญธุรกิจมากแค่ไหนสำหรับแต่ละความรับผิดชอบ?
- session EventStorming ควรจำกัดที่ไม่กี่ชั่วโมง (สองหรือสาม) ต่อครั้ง อาจต้องจัดติดต่อกันหลายวัน เช่น สามหรือสี่วัน
- กันเวลาเผื่อไว้มากพอสำหรับ การหารือและกลั่น scenario แต่พยายามใช้เวลาแต่ละ scenario ให้คุ้ม ควรหารือและทำซ้ำต่อ1 scenario ได้ภายในราว 10 ถึง 20 นาที
- สำหรับ test ต้องใช้เวลากับผู้เชี่ยวชาญธุรกิจรีวิวสิ่งที่เขียน แต่อย่าคาดหวังให้เขานั่งดูตอนเขียน code (ถ้าเขาอยู่ก็เป็นโบนัส แต่อย่าคาดหวัง) model ที่แม่นยำใช้เวลารีวิวน้อยกว่า อย่าประเมินความสามารถของผู้เชี่ยวชาญธุรกิจในการอ่าน test ต่ำเกินไป โดยเฉพาะเมื่อข้อมูลทดสอบสมจริง test ควรให้ผู้เชี่ยวชาญธุรกิจเข้าใจและยืนยันได้ราว1 test ต่อหนึ่งถึงสองนาที
- ระหว่างรีวิว test ผู้เชี่ยวชาญธุรกิจให้ input เกี่ยวกับ Aggregate, Command และ Domain Event ได้ว่ายึดภาษากลางแค่ไหน ทำได้ในเวลาอันสั้น
คำแนะนำนี้ช่วยให้ใช้เวลากับผู้เชี่ยวชาญธุรกิจในปริมาณที่พอดีและจำกัดเวลาที่ต้องใช้ไปกับพวกเขา
สรุปบทเรียน (Summary)
หัวข้อที่มีชื่อว่า “สรุปบทเรียน (Summary)”ในบทนี้เราได้เรียนรู้:
- รู้จัก EventStorming ว่าใช้อย่างไรและจัด session กับทีมอย่างไร — ทั้งหมดเพื่อเร่งความพยายามในการสร้าง model ให้เร็วขึ้น โดยใช้กระดาษโน้ตหลากสีบนผนัง ไล่จาก Domain Event (ส้ม) → Command (ฟ้า) → Aggregate (เหลือง) เรียงตามเวลา แล้วเสริมด้วย Process (ลิลลี่), จุดปัญหา (ม่วง/แดง), Bounded Context (ชมพู), View (เขียว) และบทบาทผู้ใช้
- รู้จัก เครื่องมือเสริมอื่นๆ ที่ใช้ควบคู่กับ EventStorming ได้แก่ executable specification, Impact Mapping และ User Story Mapping
- รู้วิธี ใช้ DDD บน project Agile ทั้งการจ้างคนเก่ง, การวิเคราะห์ SWOT, การยอมรับ Modeling Spike และ Modeling Debt, การประมาณการแบบ metrics-based, Timeboxed Modeling และการบริหารเวลากับผู้เชี่ยวชาญธุรกิจ
สำหรับเอกสารอ้างอิงเชิงลึกที่ครอบคลุมการนำ DDD ไป implement บน project ดูได้ใน Implementing Domain-Driven Design ของ Vaughn Vernon
- เวลาเป็นข้อจำกัดจริง ทางออกไม่ใช่การตัด design ทิ้ง แต่คือการออกแบบในแบบที่ เร่งความเร็วได้
- EventStormingEventStormingเวิร์กช็อปแบบร่วมมือ (Alberto Brandolini, 2013) ใช้กระดาษโน้ตสีติดบนผนัง: ส้ม=event, น้ำเงิน=command, เหลือง=aggregate ฯลฯ เพื่อค้นพบ model และขอบเขตของ contextProcess (Alberto Brandolini) ทำให้ทุกคนในห้อง — ทั้งนักพัฒนาและ ผู้เชี่ยวชาญธุรกิจDomain Expertผู้เชี่ยวชาญธุรกิจที่รู้กฎ กระบวนการ และความต้องการของ domain อย่างลึกซึ้ง เป็นแหล่งความรู้สำคัญที่ทีมพัฒนาต้องร่วมงานด้วยอย่างใกล้ชิดใน DDDStrategic Design — ออกแบบร่วมกันด้วยกระดาษโน้ต เร็ว ถูก และโฟกัสที่กระบวนการทางธุรกิจ
- บริหาร project DDD บน Agile ด้วย SWOTSWOT Analysisการวิเคราะห์จุดแข็ง (Strengths), จุดอ่อน (Weaknesses), โอกาส (Opportunities) และอุปสรรค (Threats) เพื่อประเมินทิศทางของ project DDD อย่างรอบด้านProcess, Modeling SpikeModeling Spikeการจัดสรรเวลา timeboxed ให้ทีมสำรวจและทดลองสร้าง model โดยไม่ต้องส่งมอบ production code เพื่อลดความเสี่ยงและเรียนรู้ domain ก่อลงมือทำจริงProcess/Modeling Debt, การประมาณการอิง metric และ Timeboxed Modeling
- จำกัดเวลากับผู้เชี่ยวชาญธุรกิจให้พอดี ทำ session ให้สนุกและคุ้มค่า เพื่อรักษา partnership ที่แข็งแรง
เจาะลึกแนวคิดในบทนี้ต่อได้ที่คลังอ้างอิง DevIQ:
- EventStorming — คำอธิบายเทคนิคเวิร์กช็อปที่บทนี้ใช้เป็นแกนหลักในการพายุ Domain Event, Command และ Aggregate ร่วมกับผู้เชี่ยวชาญธุรกิจ
- Domain Events — แพทเทิร์นเบื้องหลังโน้ตสีส้มที่เป็นจุดเริ่มต้นของทุก session EventStorming
- Aggregate — แนวคิดของโน้ตสีเหลืองอ่อนในขั้นที่ 3 ซึ่งเป็นตัวรับ Command และปล่อย Domain Event
- Bounded Context — ขอบเขตที่วาดด้วยเส้นทึบและโน้ตสีชมพูในขั้นที่ 4 ของ EventStorming
เช็กความเข้าใจ — บทที่ 7
ข้อ 1 / 4ใน EventStorming กระดาษโน้ตสีส้มใช้แทนอะไร และสร้างเป็นอันดับแรกเพราะอะไร?