ข้าม​ไป​ยัง​เนื้อหา

Strategic Design ด้วย Bounded Context และ Ubiquitous Language

ของ​สอง​ชิ้น​ที่​เรียก​ว่า Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design กับ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design นั้น​คือ​อะไร​กัน​แน่? พูด​สั้น​ที่สุด DDD คือ​การ​สร้าง model ของ Ubiquitous Language ไว้​ภายใน Bounded Context ที่​ขีด​ขอบเขต​ไว้​อย่าง​ชัดเจน — ซึ่ง​คำ​อธิบาย​แบบ​นี้​ก็​คง​ยัง​ไม่​ค่อย​ช่วย​ให้​เห็น​ภาพ​เท่าไร เรา​มา​แกะ​มัน​ออก​ที​ละ​ชั้น​กัน

graph TD
  subgraph BC["Bounded Context"]
    A["แนวคิด A"] --> B["แนวคิด B"]
    A --> C["แนวคิด C"]
  end
  UL["Ubiquitous Language — ภาษากลางที่ใช้ทั้งพูดและเขียนลงใน code"]
  BC -.- UL

อย่าง​แรก Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design คือ ขอบเขต​เชิง​ความหมาย​ตาม​บริบท (semantic contextual boundary) หมายความ​ว่า ภายใน​ขอบเขต​นี้ แต่ละ​คอมโพเนนต์ของ​ซอฟต์แวร์ model มี​ความหมาย​เฉพาะ​เจาะจง​และ​ทำ​สิ่ง​เฉพาะ​เจาะจง คอมโพเนนต์ที่​อยู่​ข้าง​ใน​ล้วน​ผูก​กับ​บริบท​และ​มี​แรง​จูงใจ​เชิง​ความหมาย​กำกับ​อยู่ แค่​นี้​ก็​เข้าใจ​ได้

ตอน​เพิ่ง​เริ่ม​ลงมือ​สร้าง model Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ยัง​ค่อน​ข้าง​เป็น​นามธรรม มอง​ได้​ว่า​เป็น​ส่วน​หนึ่ง​ของ พื้นที่​ปัญหา (Problem Space)Problem Space“พื้นที่​ปัญหา” — สิ่ง​ที่​ธุรกิจ​ต้องการ​แก้ไข อยู่​ใน​รูป​ของ Domain และ Subdomain (ยัง​ไม่​พูด​ถึง​วิธี​แก้)Strategic Design แต่​เมื่อ model เริ่ม​มี​ความหมาย​ลึก​และ​คม​ชัด​ขึ้น Bounded Context จะ​แปร​เปลี่ยน​ไป​สู่ พื้นที่​คำ​ตอบ (Solution Space)Solution Space“พื้นที่​คำ​ตอบ” — วิธี​ที่​เรา​เลือก​แก้​ปัญหา อยู่​ใน​รูป​ของ Bounded Context และ model 1 subdomain อาจ​มี​ได้​หลาย​คำ​ตอบStrategic Design อย่าง​รวดเร็ว โดย​มี​ซอฟต์แวร์ model ปรากฏ​ออก​มา​เป็น source code ของ project จำ​ไว้​ว่า Bounded Context คือ​ที่​ที่ model ถูก implement จริง และ​เรา​จะ​มี software artifact แยก​ต่างหาก​สำหรับ​แต่ละ Bounded Context


พื้นที่​ปัญหา​และ​พื้นที่​คำ​ตอบ​คือ​อะไร (What Is a Problem Space and a Solution Space?)

หัวข้อ​ที่​มีชื่อ​ว่า “พื้นที่​ปัญหา​และ​พื้นที่​คำ​ตอบ​คือ​อะไร (What Is a Problem Space and a Solution Space?)”

พื้นที่​ปัญหา (Problem Space)Problem Space“พื้นที่​ปัญหา” — สิ่ง​ที่​ธุรกิจ​ต้องการ​แก้ไข อยู่​ใน​รูป​ของ Domain และ Subdomain (ยัง​ไม่​พูด​ถึง​วิธี​แก้)Strategic Design คือ​ที่​ที่​เรา​ทำการ​วิเคราะห์​และ​ออกแบบ​เชิงกลยุทธ์​ระดับ​สูง ภาย​ใต้​ข้อ​จำกัด​ของ project หนึ่งๆ ตรง​นี้​ใช้​แค่​ไดอะแกรม​ก็​พอ ระหว่าง​ที่​ถก​เรื่อง​ตัว​ขับ​เคลื่อน​ระดับ project พร้อม​จด​เป้าหมาย​และ​ความ​เสี่ยง​สำคัญ​ไว้ Context MapContext Mapแผนภาพ​ที่​แสดง Bounded Context ทั้งหมด​และ​ความ​สัมพันธ์​ระหว่าง​กัน ช่วย​ให้​เห็น​ภาพ​รวม​และ​จุด​เชื่อม​ต่อ/แปล​ภาษา​ใน​ระบบ​ใหญ่Strategic Design ทำงาน​ได้​ดี​มาก​ใน​พื้นที่​ปัญหา และ Bounded Context ก็​นำ​มา​ใช้​ใน​การ​ถก​พื้นที่​ปัญหา​ได้​เมื่อ​จำเป็น แม้ว่า​โดย​ธรรมชาติ​มัน​จะ​ผูก​แน่น​กับ​พื้นที่​คำ​ตอบ​มากกว่า

พื้นที่​คำ​ตอบ (Solution Space)Solution Space“พื้นที่​คำ​ตอบ” — วิธี​ที่​เรา​เลือก​แก้​ปัญหา อยู่​ใน​รูป​ของ Bounded Context และ model 1 subdomain อาจ​มี​ได้​หลาย​คำ​ตอบStrategic Design คือ​ที่​ที่​เรา implement ทางออก​ที่​การ​ถก​ใน​พื้นที่​ปัญหา​ได้​ระบุ​ไว้​ว่า​เป็น Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design ของ​เรา เมื่อ Bounded Context ถูก​พัฒนา​ขึ้น​ใน​ฐานะ ความ​ริเริ่ม​เชิงกลยุทธ์​ที่​สำคัญ ของ​องค์กร เรา​เรียก​มัน​ว่า Core Domain เรา​พัฒนา​ทางออก​ใน Bounded Context นั้น​เป็น code ทั้ง main source และ test source และ​ยัง​ต้อง​ผลิต code ใน​พื้นที่​คำ​ตอบ​ที่​รองรับ​การ​เชื่อม​ต่อ (integration) กับ Bounded Context อื่น​ด้วย

ซอฟต์แวร์ model ที่​อยู่​ภายใน​ขอบเขต​นั้น​สะท้อน​ภาษา​ที่​ทีม​ใน​แต่ละ Bounded Context พัฒนา​ขึ้น​และ​พูด​กัน​ทุก​คน ภาษา​นี้​เรียก​ว่า Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design เพราะ​มัน​ทั้ง​ถูก​พูด​ใน​หมู่​สมาชิก​ทีม​และ​ถูก implement ใน​ซอฟต์แวร์ model ดังนั้น Ubiquitous Language จึง​ต้อง เคร่งครัด แม่นยำ รัดกุม และ​กระชับ ใน​ไดอะแกรม กล่อง (box) ภายใน Bounded Context แทน​แนวคิด​ของ model ซึ่ง​อาจ​ถูก implement เป็น class

เมื่อ​เทียบ​กับ​ซอฟต์แวร์​ทั้งหมด​ที่​องค์กร​ใช้ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design คือ model ที่​ติด​อันดับ​สำคัญ​ที่สุด เพราะ​มัน​คือ​หนทาง​สู่​ความ​ยิ่งใหญ่ Core Domain ถูก​พัฒนา​ขึ้น​เพื่อ สร้าง​ความ​แตก​ต่าง​ให้​องค์กร​เหนือ​คู่แข่ง​ทั้งหมด อย่าง​น้อย​ที่สุด​มัน​ต้อง​ตอบ​โจทย์​สาย​ธุรกิจ​หลัก​สาย​หนึ่ง องค์กร​เก่ง​ทุก​เรื่อง​ไม่​ได้​และ​ไม่​ควร​พยายาม​ด้วย​ซ้ำ จึง​ต้อง​เลือก​อย่าง​ชาญ​ฉลาด​ว่า​อะไร​ควร​เป็น​ส่วน​หนึ่ง​ของ Core Domain และ​อะไร​ไม่​ควร นี่​คือ​คุณค่า​หลัก​ที่ DDD เสนอ — เรา​ต้อง​ลงทุน​ให้​เหมาะสม​ด้วย​การ​ทุ่ม​ทรัพยากร​ที่​ดี​ที่สุด​ลง​ใน Core Domain

แก่น​ของ Bounded Context

Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design คือ ขอบเขต​ของ​ภาษา — ภายใน​ขอบเขต​นี้​ทุก​คำ​ใน model มี​ความหมาย​เดียว​ที่​แน่นอน ออก​นอก​เส้น​นี้ คำ​เดียวกัน​มี​สิทธิ์​หมาย​ถึง​คนละ​สิ่ง และ​นั่น​คือ​เรื่อง​ปกติ Bounded Context ที่​เป็น​ความ​ริเริ่ม​เชิงกลยุทธ์​สำคัญ​ที่สุด​เรียก​ว่า Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design — เป็น​ที่​ที่​ต้อง​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ไป


เมื่อ​มี​ใคร​ใน​ทีม​ใช้​สำนวน​จาก Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ทุก​คนใน​ทีม​เข้าใจ​ตรง​กัน​ว่า​หมาย​ถึง​อะไร อย่าง​แม่นยำ​และ​มี​ข้อ​จำกัด​ชัดเจน สำนวน​นั้น “แพร่​อยู่​ทั่ว (ubiquitous)” ภายใน​ทีม เช่น​เดียว​กับ​ภาษา​ทั้งหมด​ที่​ทีม​ใช้​นิยาม​ซอฟต์แวร์ model ที่​กำลัง​พัฒนา

ลอง​นึกถึง​ภาษา​ใน​ซอฟต์แวร์ model เหมือน​นานา​ประเทศ​ที่​ประกอบ​กัน​เป็น​ทวีป​ยุโรป ภายใน​เยอรมนี ฝรั่งเศส และ​อิตาลี ภาษา​ราชการ​ของ​แต่ละ​ประเทศ​ชัดเจน​และ​แน่นอน แต่​เมื่อ​ข้าม​พรมแดน ภาษา​ราชการ​ก็​เปลี่ยน​ไป เอเชีย​ก็​เช่น​กัน — ญี่ปุ่น​พูด​ญี่ปุ่น ส่วน​ภาษา​ที่​พูด​ใน​จีน​และ​เกาหลี​ก็​แตก​ต่าง​กัน​ชัดเจน​ตาม​เส้น​พรมแดน Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ก็​มอง​ได้​แบบ​เดียวกัน คือ​เป็น ขอบเขต​ของ​ภาษา ใน​กรณี​ของ DDD ภาษา​เหล่า​นี้​คือ​ภาษา​ที่​ทีม​เจ้าของ​ซอฟต์แวร์ model พูด​กัน และ​รูปแบบ​ลายลักษณ์​อักษร​ที่​สำคัญ​ของ​ภาษา​นั้น​ก็​คือ source code ของ model

ใน​ภาษา​มนุษย์ คำ​ศัพท์​วิวัฒน์​ตาม​กาล​เวลา และ​ข้าม​พรมแดน​คำ​เดิมๆ ก็​แฝง​นัย​ที่​ต่าง​ออก​ไป ลอง​นึกถึง​คำ​สเปน​ที่​ใช้​ใน​สเปน​กับ​คำ​เดียวกัน​ที่​ใช้​ใน​โคลอมเบีย ที่​แม้แต่​การ​ออก​เสียง​ก็​เปลี่ยน มัน​มี​ทั้ง​สเปน​แบบ​สเปน​และ​สเปน​แบบ​โคลอมเบีย ภาษา​ใน​ซอฟต์แวร์ model ก็​เช่น​กัน เป็น​ไป​ได้​ว่า​คน​จาก​ทีม​อื่น​จะ​ให้​ความหมาย​กับ​ศัพท์​เดียวกัน​ต่าง​ออก​ไป เพราะ​ความ​รู้​ทาง​ธุรกิจ​ของ​เขา​อยู่​ใน​บริบท​อื่น เขา​กำลัง​พัฒนา Bounded Context คนละ​อัน​ต่างหาก คอม​โพ​เนนต์ใดๆ ที่​อยู่​นอก​บริบท​เรา​ไม่​คาด​หวัง​ว่า​จะ​ยึด​นิยาม​เดียวกัน อัน​ที่​จริง​มัน​คง​ต่าง​กัน — จะ​เล็กน้อยหรือ​มหาศาล​ก็ตาม จาก​คอมโพเนนต์ที่​ทีม​เรา​สร้าง และ​นั่น​ไม่​เป็นไร​เลย

Bounded Context, ทีม และ repository

ควร​มี หนึ่ง​ทีม​ต่อ​หนึ่ง Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design และ​ควร​มี source code repository แยก​ต่างหาก สำหรับ​แต่ละ Bounded Context ทีม​หนึ่ง​อาจ​ทำงาน​หลาย Bounded Context ได้ แต่ หลาย​ทีม​ไม่​ควร​มา​ทำ Bounded Context เดียวกัน ให้​แยก source code และ database schema ของ​แต่ละ Bounded Context ออก​จาก​กัน​ให้​สะอาด เหมือน​ที่​เรา​แยก Ubiquitous Language และ​เก็บ acceptance test กับ unit test ไว้​คู่​กับ main source code

การ​ที่​หนึ่ง​ทีม​ทำ1 Bounded Context ตัด​โอกาส​เกิด “เซอร์ไพรส์​ไม่​พึง​ประสงค์” ที่มา​จาก​การ​ที่​ทีม​อื่น​เข้า​มา​แก้ source code ของ​เรา​โดย​สิ้นเชิง ทีม​เรา​เป็น​เจ้าของ code และ database และ​นิยาม interface อย่าง​เป็น​ทางการ​ที่​คน​อื่น​ต้อง​ใช้​ผ่าน​มัน​เข้า​มา — นี่​คือ​ประโยชน์​ข้อ​หนึ่ง​ของ​การ​ใช้ DDD

เพื่อ​ให้​เห็น​เหตุผล​ใหญ่​ข้อ​หนึ่ง​ของ​การ​ใช้ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ลอง​พิจารณา​ปัญหา​ที่​พบ​บ่อย​ใน​การ​ออกแบบ​ซอฟต์แวร์ ทีม​จำนวน​มาก​ไม่รู้​ว่า​ควร​หยุด​ยัด​แนวคิด​ลง​ใน domain model เมื่อไร model อาจ​เริ่ม​จาก​เล็ก​และ​จัดการ​ได้… แต่​แล้ว​ทีม​ก็​เพิ่ม​แนวคิด​เข้าไป​อีก อีก และ​อีก ไม่​นาน​ก็​เกิด​ปัญหา​ใหญ่ — ไม่​เพียง​แนวคิด​เยอะ​เกิน​ไป แต่​ภาษา​ของ model ก็​เริ่ม​เบลอ เพราะ​เมื่อ​พินิจ​ดู​แล้ว จริงๆ มัน​มี หลาย​ภาษา​ปน​กัน​ใน model ใหญ่​ก้อน​เดียว​ที่​สับสน​และ​ไร้​ขอบเขต

graph TD
  P["Product"] --> B["BacklogItem"]
  P --> R["Release"]
  P --> S["Sprint"]
  B --> T["Task"]
  R --> SB["ScheduledBacklogItem"]
  S --> CB["CommittedBacklogItem"]
  T --> E["EstimationLogEntry"]

เพราะ​ข้อ​บกพร่อง​นี้ ทีม​มัก​เปลี่ยน​ผลิตภัณฑ์​ซอฟต์แวร์​ใหม่​เอี่ยม​ให้​กลาย​เป็น​สิ่ง​ที่​เรียก​ว่า Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design — ก้อน​โคลน​ใหญ่​ที่​ไม่มี​อะไร​น่า​ภูมิใจ มัน​เป็น monolith และ​แย่​กว่า​นั้น​ด้วย คือ​เป็น​ระบบ​ที่​มี​หลาย model พัน​กัน​ยุ่ง​โดย​ไม่มี​ขอบเขต​ชัดเจน อาจ​ต้อง​ใช้​หลาย​ทีม​มา​ช่วย​กัน​ทำ​ซึ่ง​ยิ่ง​เป็น​ปัญหา แนวคิด​ที่​ไม่​เกี่ยว​กัน​กระจาย​ไป​ทั่ว​หลาย module เชื่อม​โยง​ด้วย element ที่​ขัดแย้ง​กันเอง ถ้า project นี้​มี test มัน​ก็​คง​รัน​นาน​มาก​จน test ถูก​ข้าม​ใน​ช่วง​ที่​สำคัญ​ที่สุด นี่​คือ​ผลผลิต​ของ​การ​พยายาม​ทำ​มาก​เกิน​ไป โดย​คน​มาก​เกิน​ไป ใน​ที่​ที่​ผิด ความ​พยายาม​จะ​พูด Ubiquitous Language ก็ได้​แต่​ภาษา​ถิ่น​ที่​แตกร้าว​และ​นิยาม​ไม่​ชัด จน​ถูก​ทิ้ง​ไป​ใน​ที่สุด ภาษา​แบบ​นี้​ไม่​ได้​ถูก​คิด​มา​อย่าง​ดี​แม้แต่​เท่ากับ​ภาษา​เอส​เปรัน​โต (ภาษา​ประดิษฐ์​ที่​ออกแบบ​มา​อย่าง​ตั้งใจ — แต่​ยัง​ถูก​คิด​มา​ดี​กว่า​ภาษา​ของ Big Ball of Mud เสีย​อีก) มัน​เป็น​แค่​ความ​ยุ่งเหยิง เหมือน Big Ball of Mud


Domain Expert และ​ตัว​ขับ​เคลื่อน​ทาง​ธุรกิจ (Domain Experts and Business Drivers)

หัวข้อ​ที่​มีชื่อ​ว่า “Domain Expert และ​ตัว​ขับ​เคลื่อน​ทาง​ธุรกิจ (Domain Experts and Business Drivers)”

บ่อย​ครั้ง​มี​คำ​ใบ้​ที่​ชัดเจน หรือ​อย่าง​น้อย​ก็​แผ่วๆ จาก​ผู้​มี​ส่วน​ได้​ส่วน​เสีย​ทาง​ธุรกิจ ที่​จะ​ช่วย​ทีม​เทคนิค​ตัดสิน​ใจ​สร้าง model ได้​ดี​ขึ้น Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design จึง​มัก​เป็น​ผล​ของ​ความ​พยายาม​อัน​ไร้​สติ​ยั้ง​ของ​ทีม​นัก​พัฒนา​ที่​ไม่​ฟัง ผู้เชี่ยวชาญ​ธุรกิจ (Domain Expert)Domain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design

การ​แบ่ง​แผนก​หรือ​กลุ่ม​งาน​ของ​ธุรกิจ​มัก​เป็น​ตัว​บ่ง​ชี้​ที่​ดี​ว่า​ขอบเขต​ของ model ควร​อยู่​ตรง​ไหน เรา​มัก​พบ Domain Expert อย่าง​น้อยหนึ่ง​คน​ต่อ1 business function แม้​สมัย​นี้​จะ​มี​แนวโน้ม​จัด​คน​ตาม project มาก​ขึ้น​และ​จัด​ตาม functional group ตาม​ลำดับ​ชั้น​การ​บริหาร​น้อย​ลง แต่​แม้​ใน model ธุรกิจ​แบบใหม่ๆ เรา​ก็​ยัง​พบ​ว่า project ถูก​จัด​ตาม​ตัว​ขับ​เคลื่อน​ทาง​ธุรกิจ​และ​ภาย​ใต้​พื้นที่​ของ​ความ​เชี่ยวชาญ​อยู่ดี

จะ​รู้​ได้​ว่า​จำเป็น​ต้อง​แบ่งแยก​แบบ​นี้ ก็​เมื่อ​พิจารณา​ว่า​แต่ละ business function มัก​มี​นิยาม​ต่าง​กัน​สำหรับ คำ​เดียวกัน ลอง​ดู​แนวคิด​ชื่อ “Policy” (กรมธรรม์) และ​ดู​ว่า​ความหมาย​ต่าง​กัน​อย่างไร​ข้าม business function ของ​ธุรกิจ​ประกันภัย เห็น​ได้​ชัด​ว่า Policy ใน​งาน Underwriting (การ​พิจารณา​รับประกัน) ต่าง​จาก Policy ใน​งาน Claims (การ​เคลม) และ Policy ใน​งาน Inspections (การ​ตรวจสอบ) อย่าง​มาก Policy ใน​แต่ละ​พื้นที่​ธุรกิจ​มี​อยู่​ด้วย​เหตุผล​ที่​ต่าง​กัน เป็น​ข้อเท็จจริง​ที่​หนี​ไม่​พ้น และ​ไม่มี​กายกรรม​ทาง​ความคิด​ใด​เปลี่ยน​มัน​ได้

ความ​ต่าง​ของ Policy ตาม business function
  • Policy ใน Underwriting: ใน​พื้นที่​ความ​เชี่ยวชาญ​ด้าน​การ​พิจารณา​รับประกัน Policy ถูก​สร้าง​ขึ้น​จาก​การ​ประเมิน​ความ​เสี่ยง​ของ​สิ่ง​ที่​เอา​ประกัน เช่น ใน​ประกัน​ทรัพย์สิน ผู้​พิจารณา​รับประกัน​จะ​ประเมิน​ความ​เสี่ยง​ที่​ผูก​กับ​ทรัพย์สิน​นั้น เพื่อ​คำนวณ​เบี้ย​ประกัน​ที่​จะ​คุ้มครอง​ทรัพย์สิน
  • Policy ใน Inspections: ใน​งาน​ประกัน​ทรัพย์สิน องค์กร​ประกัน​มัก​มี​พื้นที่​ความ​เชี่ยวชาญ​ด้าน​การ​ตรวจสอบ ที่​รับผิดชอบ​ตรวจ​ทรัพย์สิน​ที่​จะ​เอา​ประกัน ฝ่าย underwriting พึ่งพา​ข้อมูล​จาก​การ​ตรวจสอบ​อยู่​บ้าง — เพื่อ​ยืนยัน​ว่า​ทรัพย์สิน​อยู่​ใน​สภาพ​ตาม​ที่​ผู้​เอา​ประกัน​อ้าง รายละเอียด​การ​ตรวจ (ภาพถ่าย​และ​บันทึก) จะ​ผูก​กับ Policy ใน​พื้นที่ inspections และ​ข้อมูล​นี้ underwriting สามารถ​อ้าง​ถึง​เพื่อ​ต่อรอง​ค่า​เบี้ย​ขั้น​สุดท้าย​ได้
  • Policy ใน Claims: Policy ใน​พื้นที่​การ​เคลม จะ​ติดตาม​คำขอ​ชดใช้​เงิน​ของ​ผู้​เอา​ประกัน​ตาม​เงื่อนไข​ของ Policy ที่​สร้าง​ไว้​ใน​ฝั่ง underwriting Policy ฝั่ง​เคลม​จะ​อ้าง​ถึง Policy ฝั่ง underwriting อยู่​บ้าง แต่​จะ​โฟกัส​ที่​ความ​เสียหาย​ต่อ​ทรัพย์สิน​ที่​เอา​ประกัน และ​การ​พิจารณา​ของ​เจ้าหน้าที่​เคลม​ว่า​ควร​จ่าย​เงิน​หรือ​ไม่ เท่าไร

ถ้า​พยายาม​ยุบ Policy ทั้ง​สาม​แบบ​ให้​เป็น Policy เดียว​สำหรับ​ทั้ง​สาม​กลุ่ม​ธุรกิจ จะ​เจอ​ปัญหา​แน่นอน และ​ยิ่ง​เป็น​ปัญหา​หนัก​ขึ้น​ไป​อีก ถ้า​ใน​อนาคต Policy ที่​หนัก​อึ้ง​อยู่​แล้ว​ต้อง​รองรับ​แนวคิด​ทาง​ธุรกิจ​ที่​สี่​และ​ที่​ห้า​เข้า​มา​ด้วย — ไม่มี​ใคร​ได้​ประโยชน์

graph LR
  subgraph UW["Underwriting Context"]
    P1["Policy"]
  end
  subgraph CL["Claims Context"]
    P2["Policy"]
  end
  subgraph IN["Inspections Context"]
    P3["Policy"]
  end

ใน​ทาง​กลับ​กัน DDD เน้น โอบ​รับ​ความ​ต่าง​เหล่า​นี้ ด้วย​การ​แยก​ชนิด​ที่​แตก​ต่าง​กัน​ออก​ไป​คนละ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ยอมรับ​เสีย​ว่า​มัน​เป็น​คนละ​ภาษา แล้ว​ทำงาน​ไป​ตาม​นั้น มี​สาม​ความหมาย​ของ Policy หรือ? ถ้า​ใช่ ก็มี3 Bounded Context แต่ละ​อัน​มี Policy ของ​ตัวเอง​ที่​มี​คุณสมบัติ​เฉพาะ ไม่​จำเป็น​ต้อง​ตั้ง​ชื่อ​ให้​ยุ่งยาก​เป็น UnderwritingPolicy, ClaimsPolicy, หรือ InspectionsPolicy เพราะ​ชื่อ​ของ Bounded Context จัดการ scoping นั้น​ให้​แล้ว ชื่อ​จึง​เป็น​เพียง Policy เหมือน​กัน​ใน​ทั้ง3 Bounded Context

🚢 อีก​ตัวอย่าง — 'flight' ใน​สาย​การ​บิน

ใน​อุตสาหกรรม​สาย​การ​บิน คำ​ว่า “flight” มี​ได้​หลาย​ความหมาย — flight ที่​นิยาม​ว่า​เป็นการ​บิน​ขึ้น​และ​ลง​ครั้ง​เดียว​จาก​สนามบิน​หนึ่ง​ไป​อีก​ที่​หนึ่ง, flight อีก​แบบ​ที่​นิยาม​ใน​แง่​ของ​การ​ซ่อม​บำรุง​อากาศยาน, และ flight อีก​แบบ​ที่​นิยาม​ใน​แง่​ของ​การ​ออก​ตั๋ว​ผู้โดยสาร​แบบ​บิน​ตรง​หรือ​แวะ​พัก เพราะ​แต่ละ​ความหมาย​เข้าใจ​ได้​ชัด​ก็​ต่อ​เมื่อ​อยู่​ใน​บริบท​ของ​มัน แต่ละ​อัน​จึง​ควร​ถูก model ใน​คนละ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design การ​ยัด​ทั้ง​สาม​ไว้​ใน Bounded Context เดียว​มี​แต่​จะ​นำ​ไป​สู่​ความ​สับสน​พัน​กัน​ยุ่ง


เพื่อ​ให้​เหตุผล​ของ​การ​ใช้ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design เป็น​รูปธรรม​ขึ้น มา​ดู​ตัวอย่าง domain model จริง​กัน ใน​กรณี​นี้​เรา​กำลัง​ทำ application บริหาร project แบบ agile ที่​อิง Scrum แนวคิด​ศูนย์กลาง​หรือ​แนวคิด​หลัก​คือ Product ซึ่ง​แทน​ซอฟต์แวร์​ที่​จะ​สร้าง​และ​จะ​ถูก​ขัดเกลา​ตลอด​หลาย​ปี​ของ​การ​พัฒนา Product มี Backlog Item, Release, และ Sprint แต่ละ Backlog Item มี Task หลาย​ตัว และ​แต่ละ Task มี​กลุ่ม​ของ Estimation Log Entry ได้ Release มี Scheduled Backlog Item ส่วน Sprint มี Committed Backlog Item จนถึง​ตรง​นี้​ทุก​อย่าง​ยัง​ดี เรา​ระบุ​แนวคิด​หลัก​ของ domain model ได้ และ​ภาษา​ยัง​โฟกัส​และ​ไม่​แตก

แล้ว​ทีม​ก็​เริ่ม​เติม: “อ้อ​ใช่ เรา​ต้อง​มี user ด้วย และ​อยาก​เปิด​ให้​เกิด​การ​พูด​คุย​ร่วม​กัน (collaborative discussion) ภายใน​ทีม​ผลิตภัณฑ์ มา​แทน​แต่ละ​องค์กร​ที่​สมัคร​ใช้งาน​เป็น Tenant ภาย​ใต้ Tenant เรา​จะ​ให้​ลง​ทะเบียน User กี่​คน​ก็ได้ และ User จะมี Permission แล้ว​ก็​เพิ่ม​แนวคิด Discussion เป็น​หนึ่ง​ใน​เครื่องมือ​ทำงาน​ร่วม​ที่​เรา​จะ​รองรับ”

ทีม​เติม​ต่อ: “เออ ยัง​มี​เครื่องมือ​ทำงาน​ร่วม​อื่น​อีก Discussion อยู่​ภายใน Forum และ Discussion มี Post แล้ว​เรา​ก็​อยาก​รองรับ Shared Calendar ด้วย” จาก​นั้น: “อย่า​ลืม​ว่า Tenant ต้อง​ชำระ​เงิน เรา​จะ​ขาย package support เป็นระดับๆ จึง​ต้อง​มี​ทาง​ติดตาม support incident ทั้ง Support และ Payment ควร​บริหาร​ภาย​ใต้ Account” และ​ยัง​โผล่​มา​อีก: “ทุก Product แบบ Scrum มี Team เฉพาะ​ที่​ทำงาน​ให้ ประกอบ​ด้วย ProductOwner หนึ่ง​คน​และ TeamMember หลาย​คน แต่​จะ​จัดการ​เรื่อง Human Resource Utilization ยังไง​ดี? เอ… ถ้า​เรา model Schedule ของ TeamMember พร้อม​กับ utilization และ availability ของ​พวก​เขา​ล่ะ?” และ: “Shared Calendar ไม่​ควร​จำกัด​แค่ CalendarEntry ธรรมดา เรา​ควร​ระบุ​ชนิด​เฉพาะ​ของ CalendarEntry ได้ เช่น Reminder, Milestone, การ​ประชุม Planning และ Retrospective, และ Target Date”

เดี๋ยว​ก่อน! เห็น​กับดัก​ที่​ทีม​กำลัง​ตกลง​ไป​ไหม? ดู​สิ​ว่า​พวก​เขา​เตลิด​ออก​ห่าง​จาก​แนวคิด​หลัก​ดั้งเดิม — Product, Backlog Item, Release, Sprint — ไป​ไกล​แค่​ไหน ภาษา​ไม่​ได้​เป็น​เรื่อง​ของ Scrum ล้วนๆ อีก​ต่อ​ไป มัน​แตกร้าว​และ​สับสน อย่า​หลง​เชื่อ​ว่า​จำนวน​แนวคิด​ที่​ตั้ง​ชื่อ​ไว้​ยัง​ดู​จำกัด เพราะ​ทุก element ที่​ตั้ง​ชื่อ เรา​อาจ​ต้อง​มี​อีก​สอง​สาม​แนวคิด​มารองรับ​มัน ทีม​กำลัง​เดิน​หน้า​สู่​การ​ส่ง​มอบ Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design ทั้ง​ที่ project เพิ่ง​จะ​เริ่มต้น​ด้วย​ซ้ำ

graph TD
  Acc["Account"] --> SP["SupportPlan"]
  Acc --> Pay["Payment"]
  SP --> Inc["Incident"]
  Ten["Tenant"] --> Usr["User"]
  Usr --> Perm["Permission"]
  Prod["Product"] --> BI["BacklogItem"]
  Prod --> Rel["Release"]
  Prod --> Spr["Sprint"]
  BI --> Tsk["Task"]
  Tsk --> Vol["Volunteer"]
  Tsk --> ELE["EstimationLogEntry"]
  Rel --> SBI["ScheduledBacklogItem"]
  Spr --> CBI["CommittedBacklogItem"]
  Tm["Team"] --> PO["ProductOwner"]
  Tm --> TM["TeamMember"]
  RM["ResourceManager"] --> TCR["TimeConsumingResource"]
  TCR --> Sch["Schedule"]
  TCR --> Av["Availability"]
  Fo["Forum"] --> Dis["Discussion"]
  Dis --> Po["Post"]
  Cal["Calendar"] --> CE["CalendarEntry"]

DDD มี​เครื่องมือ​อะไร​ช่วย​เรา​เลี่ยง​หลุมพราง​พวก​นี้? อย่าง​น้อย​ต้อง​มี​เครื่องมือ​เชิงกลยุทธ์​พื้นฐาน​สอง​ชิ้น ชิ้น​หนึ่ง​คือ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design อีก​ชิ้น​คือ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design การ​ใช้ Bounded Context บังคับ​ให้​เรา​ตอบ​คำถาม​ว่า “อะไร​คือ core?” Bounded Context ควร​อุ้ม​แนวคิด​ที่​เป็น​แกน​ของ​ความ​ริเริ่ม​เชิงกลยุทธ์​ไว้​ใกล้​ชิด และ​ผลัก​ทุก​อย่าง​ที่​เหลือ​ออก​ไป แนวคิด​ที่​ยัง​คง​อยู่​คือ​ส่วน​หนึ่ง​ของ Ubiquitous Language ของ​ทีม นี่​คือ​วิธี​ที่ DDD ทำงาน​เพื่อ​เลี่ยง​การ​ออกแบบ application แบบ monolithic

ประโยชน์​ด้าน​การ​ทดสอบ

เพราะ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ไม่ใช่ monolith จึง​ได้​ประโยชน์​อื่น​ตาม​มา​เมื่อ​ใช้​มัน หนึ่ง​ใน​นั้น​คือ test จะ​โฟกัส​ที่ model เดียว จำนวน​จึง​น้อย​ลง​และ​รัน​เร็ว​ขึ้น แม้​นี่​จะ​ไม่ใช่​แรง​จูงใจ​หลัก​ใน​การ​ใช้ Bounded Context แต่​ก็​ให้​ผล​ตอบแทน​ใน​ทาง​อื่น​แน่นอน

แท้จริง​แล้ว​บาง​แนวคิด​จะ “อยู่​ใน​บริบท (in context)” และ​ถูกรวม​ไว้​ใน​ภาษา​ของ​ทีม​อย่าง​ชัดเจน ส่วน​แนวคิด​อื่น​จะ “อยู่​นอก​บริบท (out of context)” แนวคิด​ที่​รอด​ผ่าน​การกรอง​แบบ “เอา​เฉพาะ core” อัน​เข้มงวด​นี้ คือ​ส่วน​หนึ่ง​ของ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ของ​ทีม​ที่​เป็น​เจ้าของ Bounded Context ขอบเขต​นั้น​เอง​ที่​เน้น​ย้ำ​ความ​เคร่งครัด​ภายใน

แล้ว​จะ​รู้​ได้​อย่างไร​ว่า​อะไร​คือ core? ตรง​นี้​แหละ​ที่​ต้อง​ดึง​คน​สอง​กลุ่ม​สำคัญ​มา​รวม​เป็น​ทีม​เดียว​ที่​ร่วมมือ​และ​เป็น​อัน​หนึ่ง​อัน​เดียว — ผู้เชี่ยวชาญ​ธุรกิจ (Domain Expert)Domain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design กับ​นัก​พัฒนา​ซอฟต์แวร์

Domain Expert โดย​ธรรมชาติ​จะ​โฟกัส​ที่​เรื่อง​ธุรกิจ​มากกว่า ความคิด​ของ​พวก​เขา​หมุน​รอบ​วิสัยทัศน์​ว่า​ธุรกิจ​ทำงาน​อย่างไร ใน domain ของ Scrum เรา​คาด​ได้​ว่า Domain Expert จะ​เป็น Scrum Master ที่​เข้าใจ​อย่าง​ถ่องแท้​ว่า Scrum ถูก​นำ​ไป​ปฏิบัติ​ใน project อย่างไร

Product Owner หรือ Domain Expert?

หลาย​คน​สงสัย​ว่า Scrum product owner ต่าง​จาก Domain ExpertDomain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design ของ DDD อย่างไร บาง​กรณี​อาจ​เป็น​คน​คน​เดียวกัน​ที่​สวม​ได้​ทั้ง​สอง​บทบาท แต่​ไม่​น่า​แปลก​ใจ​ที่ product owner มัก​โฟกัส​ที่​การ​บริหาร​และ​จัด​ลำดับ​ความ​สำคัญ​ของ product backlog และ​ดูแล​ความ​ต่อ​เนื่อง​เชิง​แนวคิด​และ​เทคนิค​ของ project มากกว่า นั่น​ไม่​ได้​แปล​ว่า product owner จะ​เป็น​ผู้เชี่ยวชาญ​ใน​ความ​สามารถ​หลัก​ของ​ธุรกิจ​ที่​เรา​กำลัง​ทำ​อยู่​โดย​อัตโนมัติ ให้​แน่ใจ​ว่า​มี Domain Expert ตัว​จริง​อยู่​ใน​ทีม อย่า​เอา product owner มา​แทน​โดยที่​ขาด know-how ที่​จำเป็น

ใน​ธุรกิจ​ของ​เรา​ก็​มี Domain Expert เช่น​กัน มัน​ไม่ใช่​ตำแหน่ง​งาน แต่​อธิบาย​ถึง​คน​ที่​โฟกัส​ที่​ธุรกิจ​เป็น​หลัก mental model ของ​พวก​เขา​นี่แหละ​ที่​เรา​ใช้​เป็น​จุด​เริ่มต้น​ใน​การ​ก่อ​ร่าง​รากฐาน​ของ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ของ​ทีม

ใน​ทาง​กลับ​กัน นัก​พัฒนา​โฟกัส​ที่​การ​พัฒนา​ซอฟต์แวร์ และ​อาจ​ถูก​กลืน​กิน​ด้วย​ภาษา​โปรแกรม​และ​เทคโนโลยี (Java, C#, Scala, JavaScript, PHP, …) แต่​นัก​พัฒนา​ใน project DDD ต้อง ต้าน​แรง​ดึง​ที่​จะ​หมกมุ่น​กับ​เทคนิค​จน​รับ​โฟกัส​ทาง​ธุรกิจ​ของ​ความ​ริเริ่ม​เชิงกลยุทธ์​หลัก​ไม่​ได้ ตรง​ข้าม นัก​พัฒนา​ควร​ปฏิเสธ​ความ​รวบรัด​ที่​ไม่​จำเป็น และ​พร้อม​โอบ​รับ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ที่​ทีม​ค่อยๆ พัฒนา​ขึ้น​ภายใน Bounded Context ของ​ตน

โฟกัส​ที่​ความ​ซับซ้อน​ทาง​ธุรกิจ ไม่ใช่​ความ​ซับซ้อน​ทาง​เทคนิค

เรา​ใช้ DDD เพราะ ความ​ซับซ้อน​ของ model ธุรกิจ​สูง เรา​ไม่​เคย​อยาก​ทำให้ domain model ซับซ้อน​เกิน​กว่า​ที่​ควร​จะ​เป็น แต่​เรา​ใช้ DDD ก็​เพราะ model ธุรกิจ​ซับซ้อน​กว่า​แง่​มุม​ทาง​เทคนิค​ของ project — และ​นั่น​คือ​เหตุผล​ที่​นัก​พัฒนา​ต้อง​ลง​ไป​ขุด model ธุรกิจ​ร่วม​กับ Domain ExpertDomain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design!

ทั้ง​นัก​พัฒนา​และ Domain Expert ควร​ปฏิเสธ​แนวโน้ม​ที่​จะ​ให้ เอกสาร​ปกครอง​เหนือ​บทสนทนา Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ที่​ดี​ที่สุด​เกิด​จาก วง​ป้อน​กลับ​แบบ​ร่วมมือ (collaborative feedback loop) ที่​ดึง mental model รวม​ของ​ทีม​ออก​มา บทสนทนา​ที่​เปิด​กว้าง การ​สำรวจ และ​การ​ท้าทาย​ฐาน​ความ​รู้​ปัจจุบัน นำ​ไป​สู่​ความ​เข้าใจ​ที่​ลึก​ขึ้น​เกี่ยว​กับ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design


กลับ​มา​ที่​คำถาม “อะไร​คือ core?” โดย​ใช้ model ที่​ก่อนหน้า​นี้​บานปลาย​ควบคุม​ไม่​ได้ มา​ลอง ท้าทาย​และ​รวม​ให้​เป็น​หนึ่ง กัน

การ​ท้าทาย​ที่​ง่าย​มาก​ข้อ​หนึ่ง​คือ​ถาม​ว่า แนวคิด​แต่ละ​ตัว​ใน model ใหญ่​ยึด​ตาม Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ของ Scrum หรือ​ไม่ ตัวอย่าง​เช่น Tenant, User, และ Permission ไม่​เกี่ยว​อะไร​กับ Scrum เลย แนวคิด​เหล่า​นี้​ควร​ถูก​แยก​ออก (factored out) จาก​ซอฟต์แวร์ model Scrum ของ​เรา

Tenant, User, และ Permission ควร​ถูก​แทน​ด้วย Team, ProductOwner, และ TeamMember จริง​อยู่​ที่ ProductOwner และ TeamMember แท้จริง​ก็​คือ User ใน Tenancy หนึ่ง แต่​ด้วย ProductOwner และ TeamMember เรา​ยึด​ตาม Ubiquitous Language ของ Scrum — มัน​เป็น​คำ​ที่​เรา​ใช้​กัน​เป็น​ธรรมชาติ​เวลา​คุย​ถึง​ผลิตภัณฑ์ Scrum และ​งาน​ที่​ทีม​ทำ​กับ​มัน

SupportPlan และ Payment เป็น​ส่วน​หนึ่ง​ของ​การ​บริหาร project แบบ Scrum จริง​หรือ? คำ​ตอบ​ชัดเจน​ว่า “ไม่” จริง​ที่​ทั้ง​สอง​จะ​ถูก​บริหาร​ภาย​ใต้ Account ของ Tenant แต่​มัน​ไม่ใช่​ภาษา Scrum หลัก​ของ​เรา มัน​อยู่​นอก​บริบท​และ​ถูก​ถอด​ออก​จาก model เช่น​เดียว​กับ​เรื่อง Human Resource Utilization (ResourceManager, TimeConsumingResource, Schedule, Availability) — อาจ​มี​ประโยชน์​กับ​ใคร​สัก​คน แต่​ไม่​ได้​ถูก​ใช้​โดยตรง​โดย TeamMember ที่​อาสา (Volunteer) มาทำ Task ของ BacklogItem มัน​อยู่​นอก​บริบท

หลัง​จาก​เพิ่ม Team, ProductOwner, และ TeamMember ผู้​สร้าง model ก็​พบ​ว่า​ขาด​แนวคิด​หลัก​ที่​ให้ TeamMember ลงมือ​ทำ Task ใน Scrum สิ่ง​นี้​เรียก​ว่า Volunteer (การ​อาสา​รับ​งาน) ดังนั้น​แนวคิด Volunteer จึง​อยู่​ใน​บริบท​และ​ถูกรวม​ไว้​ใน​ภาษา​ของ model หลัก

แม้ว่า Milestone, Retrospective, และอื่นๆ ที่​อิง​ปฏิทิน​จะ​อยู่​ใน​บริบท แต่​ทีม​เลือก​เก็บ​ความ​พยายาม model ส่วน​นั้น​ไว้​ทำ​ใน sprint ถัดๆ ไป — มัน​อยู่​ใน​บริบท แต่​ตอน​นี้ อยู่​นอก scope สุดท้าย​ผู้​สร้าง model อยาก​แน่ใจ​ว่า​ได้​คำนึง​ถึง​ข้อเท็จจริง​ที่​ว่า threaded Discussion จะ​เป็น​ส่วน​หนึ่ง​ของ model หลัก จึง model Discussion ไว้ นั่น​แปล​ว่า Discussion เป็น​ส่วน​หนึ่ง​ของ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ของ​ทีม และ​จึง​อยู่​ภายใน Bounded Context

การ​ท้าทาย​เชิง​ภาษา​เหล่า​นี้​ทำให้​ได้ model ของ Ubiquitous Language ที่​สะอาด​และ​ชัดเจน​ขึ้น​มาก แต่ model Scrum จะ​ตอบ​สนอง​ความ​ต้องการ Discussion ที่​จำเป็น​อย่างไร? มัน​ต้อง​อาศัย​คอมโพเนนต์เสริม​จำนวน​มาก​จึง​จะ​ทำงาน​ได้ จึง​ดู​ไม่​เหมาะ​ที่​จะ model ไว้​ใน Scrum Bounded Context ของ​เรา อัน​ที่​จริง​ชุด Collaboration ทั้ง​ชุด​อยู่​นอก​บริบท Discussion จะ​ถูก​รองรับ​ด้วย​การ​เชื่อม​ต่อ​กับ Bounded Context อีก​อัน​หนึ่ง — Collaboration Context

graph LR
  subgraph APM["Agile Project Management Context (Core Domain)"]
    Prod["Product"] --> BI["BacklogItem"]
    Prod --> Rel["Release"]
    Prod --> Spr["Sprint"]
    BI --> Tsk["Task"]
    Tsk --> Vol["Volunteer"]
    Tsk --> ELE["EstimationLogEntry"]
    Rel --> SBI["ScheduledBacklogItem"]
    Spr --> CBI["CommittedBacklogItem"]
    Tm["Team"] --> PO["ProductOwner"]
    Tm --> TM["TeamMember"]
    Dis1["Discussion (ใช้งาน)"]
  end
  subgraph COL["Collaboration Context"]
    Fo["Forum"] --> Dis2["Discussion (ต้นทาง)"]
    Dis2 --> Po["Post"]
    Cal["Calendar"] --> CE["CalendarEntry"]
  end
  APM -.- COL

หลัง​จาก​เดิน​ผ่าน​กระบวนการ​นี้ เรา​เหลือ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design จริงๆ ที่​เล็ก​ลง​มาก แน่นอน​ว่า Core Domain จะ​เติบโต​ต่อ​ไป เรา​รู้​อยู่​แล้ว​ว่า Planning, Retrospective, Milestone และ model ที่​อิง​ปฏิทิน​ที่​เกี่ยวข้อง​ต้อง​ถูก​พัฒนา​ใน​เวลา​อัน​ควร แต่ model จะ​เติบโต​ก็​ต่อ​เมื่อ แนวคิด​ใหม่​ยึด​ตาม Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ของ Scrum เท่านั้น

ส่วน​แนว​คิดอื่นๆ ที่​ถูก​ถอด​ออก​จาก Core Domain ล่ะ? เป็น​ไป​ได้​สูง​ว่า​หลาย​ตัว ถ้า​ไม่ใช่​ทั้งหมด จะ​ถูก​ประกอบ​ขึ้น​เป็น Bounded Context ของ​ตัวเอง แต่ละ​อัน​ยึด​ตาม Ubiquitous Language ของ​มัน​เอง และ​ภายหลัง​เรา​จะ​ได้​เห็น​วิธี​เชื่อม​ต่อ​กับ​พวก​มัน​ด้วย Context MappingContext Mappingกิจกรรมการ​ระบุ Bounded Context และ​นิยาม​ความ​สัมพันธ์​ระหว่าง​กัน (เช่น Partnership, Shared Kernel, ACL) เพื่อ​จัดการ​การ​เชื่อม​ต่อ​ระหว่าง​ทีม/ระบบStrategic Design


แล้ว​จะ​ลงมือ​พัฒนา Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ภายใน​ทีมจริงๆ อย่างไร? Ubiquitous Language เกิด​จาก​ชุด​คำ​นาม​ที่​รู้จัก​กัน​ดี​หรือ​เปล่า? คำ​นาม​สำคัญ​ก็​จริง แต่​บ่อย​ครั้ง​นัก​พัฒนา​ให้​น้ำหนัก​กับ​คำ​นาม​ใน domain model มาก​เกิน​ไป จน​ลืม​ว่า​ภาษา​พูด​ประกอบ​ด้วย​อะไร​มากกว่า​คำ​นาม​เยอะ ที่​ผ่าน​มา​เรา​โฟกัส​คำ​นาม​ใน Bounded Context ตัวอย่าง​เป็น​หลัก ก็​เพราะ​เรา​สนใจ​อีก​แง่​มุม​หนึ่ง​ของ DDD คือ​การ​บีบ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design ให้​เหลือ​เฉพาะ element ที่​จำเป็น

อย่า​จำกัด Core Domain ไว้​แค่​คำ​นาม แต่​ให้​พิจารณา​แสดง Core Domain เป็น ชุด​ของ scenario ที่​เป็น​รูปธรรม เกี่ยว​กับ​สิ่ง​ที่ domain model ควร​ทำ คำ​ว่า “scenario” ใน​ที่​นี้​ไม่​ได้​หมาย​ถึง use case หรือ user story แต่​หมาย​ถึง scenario ใน​แง่​ว่า domain model ควร​ทำงาน​อย่างไร — คอมโพเนนต์ต่างๆ ทำ​อะไร สิ่ง​นี้​ทำได้​สมบูรณ์​ที่สุด​ด้วย​การ​ร่วมมือ​กัน​เป็น​ทีม​ของ​ทั้ง Domain Expert และ​นัก​พัฒนา​เท่านั้น

เร่ง​การ​ค้น​พบ​ของ​คุณ

ลอง​ทำ EventStormingEventStormingเวิร์กช็อป​แบบ​ร่วมมือ (Alberto Brandolini, 2013) ใช้​กระดาษ​โน้ต​สี​ติด​บน​ผนัง: ส้ม=event, น้ำเงิน=command, เหลือง=aggregate ฯลฯ เพื่อ​ค้น​พบ model และ​ขอบเขต​ของ contextProcess สัก​สอง​สาม​รอบ​ขณะ​ทำงาน​กับ scenario ของ​คุณ มัน​ช่วย​ให้​เข้าใจ​อย่าง​รวดเร็ว​ว่า​ควร​ทำ scenario ไหน​ก่อน​และ​จัด​ลำดับ​อย่างไร และ​ใน​ทาง​กลับ​กัน การ​พัฒนา scenario ที่​เป็น​รูปธรรม​ก็​ให้​ไอเดีย​ที่​ดี​ขึ้น​ว่า​ควร​เดิน EventStormingEventStormingเวิร์กช็อป​แบบ​ร่วมมือ (Alberto Brandolini, 2013) ใช้​กระดาษ​โน้ต​สี​ติด​บน​ผนัง: ส้ม=event, น้ำเงิน=command, เหลือง=aggregate ฯลฯ เพื่อ​ค้น​พบ model และ​ขอบเขต​ของ contextProcess ไป​ทาง​ไหน ทั้ง​สอง​เป็น​เครื่องมือ​ที่​ทำงาน​เข้าขา​กัน​ได้​ดี (Vernon อธิบาย EventStorming ของ Alberto Brandolini ไว้​ใน​บท “เครื่องมือ​เร่ง​และ​บริหาร​การนำ​ไป​ใช้”)

นี่​คือ​ตัวอย่าง scenario ที่​เข้า​กับ Ubiquitous Language ของ Scrum:

เปิด​ให้ backlog item แต่ละ​ตัว​สามารถ commit เข้า sprint ได้ โดย backlog item จะ commit ได้​ก็​ต่อ​เมื่อ​มัน​ถูก schedule สำหรับ release แล้ว ถ้า​มัน​ถูก commit ไว้​กับ sprint อื่น​อยู่ ต้อง​ยกเลิก commit นั้น​ก่อน เมื่อ commit เสร็จ ให้​แจ้ง​ฝ่าย​ที่​เกี่ยวข้อง

— scenario เริ่มต้น (Vaughn Vernon, Domain-Driven Design Distilled)

สังเกต​ว่า​นี่​ไม่ใช่ scenario เรื่อง​ที่ “มนุษย์” ใช้ Scrum ใน project อย่างไร เรา​ไม่​ได้​พูด​ถึง​ขั้นตอน​ของ​คน แต่ scenario นี้​อธิบาย​ว่า คอมโพเนนต์ของ​ซอฟต์แวร์ model ถูก​ใช้​รองรับ​การ​บริหาร project แบบ Scrum อย่างไร scenario นี้​ยัง​ไม่​สมบูรณ์​แบบ และ​ข้อดี​ของ DDD คือ​เรา​คอย​มอง​หา​ทาง​ปรับปรุง model อยู่​ตลอด เรา​ได้ยิน​คำ​นาม แต่ scenario ไม่​ได้​จำกัด​เรา​ไว้​แค่​คำ​นาม เรา​ได้ยิน​คำ​กริยา คำ​วิเศษณ์ และ​ไว​ยากรณ์อื่นๆ ด้วย เรา​ได้ยิน​ว่า​มี​ข้อ​จำกัด (constraint) — เงื่อนไข​ที่​ต้อง​เป็น​จริง​ก่อน scenario จะ​จบ​ลง​ได้​สำเร็จ ประโยชน์​สำคัญ​และ​ทรง​พลัง​ที่สุด​คือ เรา​สามารถ มี​บทสนทนา​เรื่อง​การ​ทำงาน​ของ domain model ได้จริงๆ นั่น​คือ design ของ​มัน

เรา​วาด​ภาพ​และ​ไดอะแกรม​ได้ ทั้งหมด​นี้​ทำ​เพื่อ​สื่อสาร​กัน​ใน​ทีม​ให้​ดี แต่​ขอ​เตือน​สัก​นิด ระวัง​เรื่อง​เวลา​ที่​ใช้​คอย​อัปเดต scenario เป็น​ลายลักษณ์​อักษร ภาพ​วาด และ​ไดอะแกรม ให้​ทันสมัย​ใน​ระยะ​ยาว — สิ่ง​เหล่า​นั้น ไม่ใช่ domain model มัน​เป็น​เพียง​เครื่องมือ​ช่วย​พัฒนา domain model ใน​ที่สุด code คือ model และ model คือ code พิธีรีตอง​มี​ไว้​สำหรับ​โอกาส​พิเศษ เช่น​งาน​แต่งงาน ไม่ใช่​สำหรับ domain model นี่​ไม่​ได้​แปล​ว่า​ให้​เลิก​ทำ scenario ให้​สด​ใหม่ แต่​ให้​ทำ​เท่า​ที่​มัน​ยัง​ช่วย​มากกว่า​จะ​เป็น​ภาระ

จะ​ปรับปรุง Ubiquitous Language ใน​ตัวอย่าง​ก่อนหน้า​อย่างไร​ดี? อะไร​ขาด​ไป? ไม่​นาน​เรา​คง​อยาก​เข้าใจ​ว่า “ใคร” เป็น​คน commit backlog item เข้า sprint ลอง​เติม “ใคร” เข้าไป:

product owner เป็น​ผู้ commit backlog item แต่ละ​ตัว​เข้า sprint…

หลาย​กรณี​เรา​ควร​ตั้ง​ชื่อ persona แต่ละ​ตัว​ที่​เกี่ยวข้อง​ใน scenario และ​ให้​คุณสมบัติ​ที่​จำแนก​ได้แก่​แนว​คิดอื่นๆ เช่น backlog item และ sprint แต่​ใน​กรณี​นี้​ยัง​ไม่มี​เหตุผล​หนักแน่น​พอที่​จะ​ตั้ง​ชื่อ product owner หรือ​บรรยาย backlog item และ sprint เพิ่ม เพราะ​ทุก product owner, backlog item, และ sprint จะ​ทำงาน​เหมือน​กัน​ไม่​ว่า​จะ​มี persona ที่​เป็น​รูปธรรม​หรือ​ไม่ ใน​กรณี​ที่​การ​ตั้ง​ชื่อ​ช่วย​ได้ ก็​ให้​ใช้:

product owner ชื่อ Isabel commit backlog item “View User Profile” เข้า sprint “Deliver User Profiles”…

หยุด​คิด​สัก​ครู่ ไม่ใช่​ว่า product owner เป็น​คน​เดียว​ที่​รับผิดชอบ​ตัดสิน​ใจ​ว่า backlog item จะ​ถูก commit เข้า sprint ทีม Scrum คง​ไม่​ชอบใจ​นัก เพราะ​พวก​เขา​จะ​ถูก​ผูกมัด​ให้​ส่ง​มอบ​งาน​ใน​กรอบ​เวลา​ที่​ตัวเอง​ไม่​ได้​มี​ส่วน​กำหนด ถึง​อย่าง​นั้น สำหรับ​ซอฟต์แวร์ model อาจ​เป็นการ​ปฏิบัติ​ที่สุด​ที่​ให้​คน​คน​เดียว​รับผิดชอบ​ลงมือ action นี้ เรา​จึง​ระบุ​ว่า​เป็น​บทบาท product owner ที่​ทำ แต่​ธรรมชาติ​ของ​ทีม Scrum ก็​บังคับ​ให้​เกิด​คำถาม​ว่า “มี​อะไร​ที่​สมาชิก​ทีม​ที่​เหลือ​ต้อง​ทำ​ก่อน เพื่อ​ให้ product owner ทำการ commit ได้​หรือ​ไม่?”

เห็น​ไหม​ว่า​เกิด​อะไร​ขึ้น? ด้วย​การ ท้าทาย model ด้วย​คำถาม “ใคร” เรา​ถูก​นำ​ไป​สู่​โอกาส​ที่​จะ​เข้าใจ model ลึก​ขึ้น บางที​เรา​ควร​กำหนด​ให้​มี ฉันทา​มติ​ของ​ทีม​ระดับ​หนึ่ง ว่า backlog item ถูก commit ได้ ก่อน​จะ​อนุญาต​ให้ product owner ลงมือ commit จริง นำ​ไป​สู่ scenario ที่​ขัดเกลา​แล้ว:

product owner commit backlog item เข้า sprint โดย backlog item จะ commit ได้​ก็​ต่อ​เมื่อ​มัน​ถูก schedule สำหรับ release แล้ว และ​มี​สมาชิก​ทีม​จำนวน​หนึ่ง​เป็น quorum ที่​อนุมัติ​การ commit แล้ว…

เอา​ล่ะ ตอน​นี้​เรา​ได้ Ubiquitous Language ที่​ขัดเกลา​ขึ้น เพราะ​เรา​ระบุ​แนวคิด model ใหม่​ชื่อ quorum ออก​มา​ได้ เรา​ตัดสิน​ว่า​ต้อง​มี quorum ของ​สมาชิก​ทีม​ที่​เห็น​พ้อง​ว่า​ควร commit backlog item และ​ต้อง​มี​วิธี​ให้​พวก​เขา approve การ commit นั่น​นำ​แนวคิด model ใหม่​และ​ไอเดีย​ที่​ว่า user interface จะ​ต้อง​อำนวย​การ​โต้ตอบ​เหล่า​นี้​ของ​ทีม​เข้า​มา เห็น​นวัตกรรม​ที่​ค่อยๆ คลี่​ออก​ไหม?

ยัง​มี “ใคร” อีก​ตัว​ที่​หาย​ไป​จาก model ตัว​ไหน? scenario เปิด​ของ​เรา​จบ​ด้วย “เมื่อ commit เสร็จ ให้​แจ้ง​ฝ่าย​ที่​เกี่ยวข้อง” ใคร​หรือ​อะไร​คือ​ฝ่าย​ที่​เกี่ยวข้อง? คำถาม​นี้​นำ​ไป​สู่​ความ​เข้าใจ​ที่​ลึก​ขึ้น ใคร​ต้อง​รู้​เมื่อ backlog item ถูก commit เข้า sprint? อัน​ที่​จริง element model ที่​สำคัญ​คือ sprint เอง — sprint ต้อง​ติดตาม​ยอด commit รวม​และ​ความ​พยายาม​ที่​ต้อง​ใช้​ส่ง​มอบ​ทุก task ของ sprint ประเด็น​สำคัญ​ตอน​นี้​คือ sprint ต้อง​ถูก​แจ้ง​เมื่อ​มี backlog item ถูก commit เข้า​มา:

ถ้า​มัน​ถูก commit ไว้​กับ sprint อื่น​อยู่ ต้อง​ยกเลิก commit นั้น​ก่อน เมื่อ commit เสร็จ ให้​แจ้ง​ทั้ง sprint ที่​ถูก​ยกเลิก commit ออก​ไป และ sprint ที่​ถูก commit เข้า​มา​ใหม่

ตอน​นี้​เรา​มี domain scenario ที่​ดี​พอควร ประโยค​ปิด​ท้าย​ยัง​นำ​เรา​ไป​สู่​ความ​เข้าใจ​ว่า backlog item กับ sprint อาจ​ไม่​จำเป็น​ต้อง​รับรู้​การ commit ใน​เวลา​เดียวกัน ต้อง​ไป​ถาม​ฝั่ง​ธุรกิจ​ให้​แน่ใจ แต่​ฟัง​ดู​เป็น​จุด​ที่​เหมาะ​จะ​นำ ความ​ถูกต้อง​ที่​ตาม​มา​ทีหลัง (Eventual Consistency)Eventual Consistencyความ​ถูกต้อง​ที่ “ตาม​มา​ทีหลัง” ไม่ใช่​ทันที ใช้​กับ​การ​อัปเดต​ข้าม Aggregate ผ่าน Domain Event แทน​การ​บังคับ​ให้​ตรง​กัน​ใน​ทันที​ภายใน transaction เดียวTactical Design เข้า​มา — และ​จะ​ได้​เห็น​ว่า​มัน​สำคัญ​และ​ทำได้​อย่างไร​ใน​บท​เรื่อง Aggregate

scenario ที่​ขัดเกลา​ฉบับ​เต็ม​จึง​เป็น​แบบ​นี้:

product owner commit backlog item เข้า sprint โดย backlog item จะ commit ได้​ก็​ต่อ​เมื่อ​มัน​ถูก schedule สำหรับ release แล้ว และ​มี​สมาชิก​ทีม​จำนวน​หนึ่ง​เป็น quorum ที่​อนุมัติ​การ commit แล้ว ถ้า​มัน​ถูก commit ไว้​กับ sprint อื่น​อยู่ ต้อง​ยกเลิก commit นั้น​ก่อน เมื่อ commit เสร็จ ให้​แจ้ง​ทั้ง sprint ที่​ถูก​ยกเลิก commit ออก​ไป และ sprint ที่​ถูก commit เข้า​มา​ใหม่

ใน​ทาง​ปฏิบัติ​ซอฟต์แวร์ model จะ​ทำงาน​อย่างไร? ลอง​จินตนาการ user interface ที่​สร้างสรรค์​รองรับ model นี้ ขณะ​ทีม Scrum กำลัง​ร่วม session วางแผน sprint สมาชิกใช้สมาร์ต​โฟน​หรือ​อุปกรณ์​มือถือ​เพิ่ม​การ​อนุมัติ​ของ​ตน​ให้​แก่ backlog item แต่ละ​ตัว​ขณะ​ถก​และ​ตกลง​กัน​ว่า​จะ​ทำ​ใน sprint หน้า ฉันทา​มติ​ของ quorum ที่​อนุมัติ backlog item แต่ละ​ตัว ให้​อำนาจ product owner ใน​การ commit backlog item ที่​อนุมัติ​แล้ว​ทั้งหมด​เข้า sprint

หลาย​คน​อาจ​สงสัย​ว่า​จะ​เปลี่ยน​จาก scenario ที่​เป็น​ลายลักษณ์​อักษร​ไป​เป็น artifact บาง​อย่าง​ที่​ใช้​ตรวจสอบ domain model เทียบ​กับ specification ของ​ทีม​ได้​อย่างไร มี​เทคนิค​ชื่อ Specification by Example (หรือ​ที่​เรียก​ว่า Behavior-Driven Development / BDD) ที่​ใช้ได้ สิ่ง​ที่​เรา​พยายาม​ทำ​คือ​พัฒนา​และ​ขัดเกลา Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design ร่วม​กัน สร้าง model ที่​มี​ความ​เข้าใจ​ร่วม และ​พิจารณา​ว่า model ยึด​ตาม specification หรือ​ไม่ ด้วย​การ​สร้าง acceptance test นี่​คือ​วิธี​เขียน scenario ก่อนหน้า​นี้​ใหม่​ใน​รูป​ของ executable specification:

commit-backlog-item.feature
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

เมื่อ​เขียน scenario ใน​รูป​นี้ เรา​สร้าง backing code และ​ใช้​เครื่องมือ execute specification นี้​ได้ แม้​ไม่มี​เครื่องมือ เรา​ก็​อาจ​พบ​ว่า​รูปแบบ given/when/then นี้​ทำงาน​ได้​ดี​กว่า​รูปแบบ scenario แบบ​เดิม

เรา​ไม่​จำเป็น​ต้อง​ใช้​รูปแบบ executable specification นี้​เพื่อ​ตรวจสอบ domain model เทียบ​กับ scenario ก็ได้ ใช้ unit testing framework ทำ​สิ่ง​เดียวกัน​ได้ โดย​สร้าง acceptance test (ไม่ใช่ unit test) ที่​ตรวจสอบ domain model:

ShouldCommitBacklogItemToSprint.java
/*
* product owner commit backlog item เข้า sprint
* backlog item จะ commit ได้ก็ต่อเมื่อถูก schedule สำหรับ release แล้ว
* และมี quorum ของสมาชิกทีมอนุมัติการ commit แล้ว
* เมื่อ commit เสร็จ ให้แจ้ง sprint ที่ถูก commit เข้ามา
*/
@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
assertTrue(backlogItem.isCommitted());
var backlogItemCommitted =
backlogItem.events().ofType(BacklogItemCommitted.class).singleOrDefault();
assertNotNull(backlogItemCommitted);
}

วิธี​อิง unit test เพื่อ​ทำ acceptance testing นี้​บรรลุ​เป้าหมาย​เดียว​กับ executable specification ข้อ​ได้​เปรียบ​คือ​เขียน scenario validation ได้​รวดเร็ว​กว่า แลก​กับ​ความ​อ่าน​ง่าย​ที่​ลด​ลง​บ้าง แต่ Domain ExpertDomain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design ส่วน​ใหญ่​ก็ตาม code นี้​ได้​โดย​มี​นัก​พัฒนา​ช่วย​เล็กน้อย เมื่อ​ใช้​วิธี​นี้ ควร​เก็บ scenario รูป​เอกสาร​ไว้​คู่​กับ validation code ใน​รูป​คอมเมนต์ ดัง​ใน​ตัวอย่าง

ไม่​ว่า​จะ​เลือก​วิธี​ไหน ทั้ง​สอง​มัก​ใช้​ใน​แบบ red-green (fail-pass) คือ specification จะ fail ก่อน​เมื่อ​รัน​ครั้ง​แรก เพราะ​ยัง​ไม่มี implement แนวคิด domain model ให้​ตรวจสอบ แล้ว​เรา​ค่อยๆ ขัดเกลา domain model ผ่าน​ชุด​ผลลัพธ์ red จน​รองรับ specification ครบ​และ validation ผ่าน (เห็น green ทั้งหมด) acceptance test เหล่า​นี้​จะ​ผูก​กับ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design โดยตรง​และ​เก็บ​ไว้​ใน source code repository ของ​มัน

หลาย​คน​อาจ​สงสัย​ว่า​ควร​ดูแล Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design อย่างไร​เมื่อ​นวัตกรรม​หยุด​ลง​และ​เข้า​สู่​การ maintenance อัน​ที่​จริง​การ​เรียนรู้​ที่​ดี​ที่สุด​บาง​ส่วน หรือ​การ​ได้​มา​ซึ่ง​ความ​รู้ เกิด​ขึ้น​ตลอด​ช่วง​เวลา​ยาวนาน แม้​ใน​ช่วง​ที่​บาง​คน​เรียก​ว่า “maintenance” ก็ตาม เป็น​ความ​ผิดพลาด​ที่​ทีม​จะ​มอง​ว่านวัตกรรม​จบ​ลง​เมื่อ maintenance เริ่มต้น

บางที​สิ่ง​ที่​แย่​ที่สุด​คือ​การ​แปะ​ป้าย “maintenance phase” ลงบน Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design กระบวนการ​เรียนรู้​ต่อ​เนื่อง​ไม่ใช่ “เฟส” เลย Ubiquitous Language ที่​พัฒนา​ขึ้น​ใน​ช่วง​ต้น​ต้อง​เติบโต​ต่อ​เนื่อง​เมื่อ​ปี​ผ่าน​ไป จริง​อยู่​ที่​มัน​อาจ​ค่อยๆ มี​นัย​สำคัญ​น้อย​ลง​ใน​ที่สุด แต่​คง​อีก​นาน ทั้งหมด​นี้​เป็น​ส่วน​หนึ่ง​ของ​พันธะ​ที่​องค์กร​มี​ต่อ​ความ​ริเริ่ม​หลัก ถ้า​ให้​พันธะ​ระยะ​ยาว​นี้​ไม่​ได้ — model ที่​เรา​กำลัง​ทำ​อยู่​วัน​นี้​เป็น​ตัว​สร้าง​ความ​แตก​ต่าง​เชิงกลยุทธ์ เป็น Core Domain จริง​หรือ?


อีก​คำถาม​ที่​หลาย​คน​อาจ​สงสัย — ภายใน Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design มี​อะไร​อยู่​บ้าง? เมื่อ​ดู​จาก​ไดอะแกรม​สถาปัตยกรรม Ports and Adapters (Hexagonal)Hexagonal Architectureสถาปัตยกรรม “Ports and Adapters” โดย Alistair Cockburn — วาง domain ไว้​ตรง​กลาง นิยาม port (interface) ให้ adapter ภายนอก​มา​เสียบ ทุก dependency ชี้​เข้าหา domainArchitecture จะ​เห็น​ว่า Bounded Context ประกอบ​ด้วย​มากกว่า​แค่ domain model

graph LR
  IN["Input Adapter<br/>(UI controller, REST endpoint, message listener)"] --> AS["Application Service<br/>(orchestrate use case, จัดการ transaction)"]
  AS --> DM["Domain Model<br/>(Entity, Business Logic, Domain Event)"]
  DM --> OUT["Output Adapter<br/>(persistence, message sender)"]

ชั้น (layer) เหล่า​นี้​พบ​ได้​ทั่วไป​ใน Bounded Context — Input AdapterAdapterตัว​ที่ “ทำให้” port เป็น​จริง เช่น PostgresCargoRepository หรือ REST controller อยู่​ชั้น​นอก​และ​พึ่งพา domain ทำให้​สลับ​เทคโนโลยี​ได้​โดย​ไม่​แตะ domainArchitecture เช่น UI controller, REST endpoint, และ message listener; Application ServiceApplication Serviceบริการ​ที่ “ประสาน​งาน” use case — จัดการ transaction, ความ​ปลอดภัย, การ​บันทึก, แปลง DTO — แต่​ไม่มี​กฎ​ธุรกิจ​อยู่​ใน​ตัว​มัน​เองTactical Design ที่​ประสาน use case และ​จัดการ transaction; domain model ที่​เรา​โฟกัส​กัน​มา; และ Output AdapterAdapterตัว​ที่ “ทำให้” port เป็น​จริง เช่น PostgresCargoRepository หรือ REST controller อยู่​ชั้น​นอก​และ​พึ่งพา domain ทำให้​สลับ​เทคโนโลยี​ได้​โดย​ไม่​แตะ domainArchitecture เช่น​การ​จัดการ persistence และ​ตัว​ส่ง message มี​อะไร​ให้​พูด​ถึง​อีก​มาก​เกี่ยว​กับ​ชั้น​ต่างๆ ใน​สถาปัตยกรรม​นี้ ซึ่ง​ละเอียด​เกิน​กว่า​จะ​กล่าว​ใน​หนังสือ​ฉบับ​กลั่น​นี้

Domain Model ที่​ปลอด​เทคโนโลยี

แม้​เทคโนโลยี​จะ​กระจาย​อยู่​ทั่ว​สถาปัตยกรรม แต่ domain model ควร​ปลอด​จาก​เทคโนโลยี เหตุผล​หนึ่ง​คือ — นั่น​จึง​เป็น​เหตุผล​ที่ transaction ถูก​จัดการ​โดย Application ServiceApplication Serviceบริการ​ที่ “ประสาน​งาน” use case — จัดการ transaction, ความ​ปลอดภัย, การ​บันทึก, แปลง DTO — แต่​ไม่มี​กฎ​ธุรกิจ​อยู่​ใน​ตัว​มัน​เองTactical Design ไม่ใช่​โดย domain model

Ports and AdaptersHexagonal Architectureสถาปัตยกรรม “Ports and Adapters” โดย Alistair Cockburn — วาง domain ไว้​ตรง​กลาง นิยาม port (interface) ให้ adapter ภายนอก​มา​เสียบ ทุก dependency ชี้​เข้าหา domainArchitecture ใช้​เป็น​สถาปัตยกรรม​รากฐาน​ได้ แต่​ไม่ใช่​ทาง​เลือก​เดียว​ที่​ใช้​คู่​กับ DDD ได้ เรา​ใช้ DDD ร่วม​กับ​สถาปัตยกรรม​หรือ architecture pattern เหล่า​นี้ (และอื่นๆ) ได้ โดย​ผสมผสาน​ตาม​ต้องการ:

  • Event-Driven Architecture และ Event SourcingEvent Sourcingเก็บ​ทุก​การ​เปลี่ยน​สถานะ​เป็น event ที่​เปลี่ยน​ไม่​ได้ แล้ว​สร้าง​สถานะ​ปัจจุบัน​ด้วย​การ​เล่น event ซ้ำ มัก “ต้อง​ใช้​คู่​กับ CQRS” (Greg Young) มี event stream ต่อ1 AggregateArchitecture (จะ​กล่าว​ใน​บท​เรื่อง Domain Event)
  • CQRSCQRSCommand Query Responsibility Segregation — แยก model สำหรับ “เขียน/แก้ไข” (command) ออก​จาก model สำหรับ “อ่าน” (query) เหมาะ​กับ domain ซับซ้อน แต่​เพิ่ม​ความ​ซับซ้อน ใช้​อย่าง​ระมัดระวังArchitecture — Command Query Responsibility Segregation
  • Reactive และ Actor Model — ดู​แนวคิด Actor model ที่​ใช้​คู่​กับ DDD
  • REST — Representational State Transfer
  • SOA — Service-Oriented Architecture
  • Microservices — ตาม​หนังสือ Building Microservices microservice แทบ​จะ​เทียบ​เท่ากับ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ของ DDD
  • Cloud Computing — รองรับ​ใน​ลักษณะ​เดียว​กับ microservices
Microservice เล็ก​กว่า Bounded Context?

บาง​คน​มอง microservice ว่า​เล็ก​กว่า Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ของ DDD มาก โดย​นิยาม​นั้น microservice 1 model เพียง​แนวคิด​เดียว​และ​จัดการ​ข้อมูล​ชนิด​แคบๆ เช่น microservice หนึ่ง​เป็น Product อีก​อัน​เป็น BacklogItem ถ้า​นี่​คือ granularity ที่​คุณ​มอง​ว่า​เป็น microservice ที่​คุ้ม​ค่า ก็​ให้​เข้าใจ​ว่า​ทั้ง microservice Product และ BacklogItem ยัง​คง​อยู่​ใน Bounded Context เชิง​ตรรกะ​ที่​ใหญ่​กว่า​เดียวกัน คอมโพเนนต์ microservice เล็กๆ สอง​ตัว​นี้​เพียง​มี deployment unit ต่าง​กัน (ซึ่ง​อาจ​ส่ง​ผล​ต่อ​วิธี​ที่​มัน​โต้ตอบ​กัน — ดู​เรื่อง Context MappingContext Mappingกิจกรรมการ​ระบุ Bounded Context และ​นิยาม​ความ​สัมพันธ์​ระหว่าง​กัน (เช่น Partnership, Shared Kernel, ACL) เพื่อ​จัดการ​การ​เชื่อม​ต่อ​ระหว่าง​ทีม/ระบบStrategic Design) แต่​ใน​เชิง​ภาษา มัน​ยัง​อยู่​ใน​ขอบเขต​เชิง​บริบท​และ​ความหมาย​แบบ Scrum เดียวกัน


ใน​บท​นี้​เรา​ได้​เรียนรู้: หลุมพราง​สำคัญ​บาง​อย่าง​ของ​การ​ยัด​มาก​เกิน​ไป​ใน model เดียว​จน​กลาย​เป็น Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design; การ​ประยุกต์​ใช้ strategic design ของ DDD; การ​ใช้ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design และ Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design; วิธี​ท้าทาย​สมมติฐาน​ของ​ตัวเอง​และ​รวม model ให้​เป็น​หนึ่ง; วิธี​พัฒนา Ubiquitous Language; คอมโพเนนต์เชิง​สถาปัตยกรรม​ที่​พบ​ภายใน Bounded Context; และ​ที่​สำคัญ — DDD ไม่​ได้​ยาก​เกิน​กว่า​จะ​ลงมือ​ใช้​เอง​ได้!

หัวใจ​ของ​ทั้ง​บท​คือ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design เป็น​ขอบเขต​ของ​ภาษา ภายใน​นั้น Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design สอดคล้อง​กัน 100% และ​ถูก​กลั่น​ร่วม​กัน​ระหว่าง​นัก​พัฒนา​กับ Domain ExpertDomain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design ผ่าน​บทสนทนา การ​ท้าทาย และ scenario ที่​เป็น​รูปธรรม สิ่ง​ที่​รอด​ผ่าน​การกรอง “เอา​เฉพาะ core” คือ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design ที่​เรา​ต้อง​ทุ่ม​ลงทุน​มาก​ที่สุด

สรุป​ประเด็น​สำคัญ
  • Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design = ขอบเขต​เชิง​ความหมาย ภายใน​นั้น​ทุก​คำ​มี​ความหมาย​เดียว​แน่นอน คำ​เดียวกัน (เช่น Policy, flight) มี​ได้​หลาย​ความหมาย​ข้าม context
  • Ubiquitous LanguageUbiquitous Languageภาษา​กลาง​ที่​ทุก​คนใน​ทีม (ทั้ง​นัก​พัฒนา​และ​ผู้เชี่ยวชาญ​ธุรกิจ) ใช้​ร่วม​กัน อิง​กับ domain model โดยตรง คำ​เดียวกัน​ต้อง​หมาย​ถึง​สิ่ง​เดียวกัน และ​สะท้อน​ลง​ใน codeStrategic Design คือ​ภาษา​กลาง​ที่​ทั้ง​พูด​และ​ฝัง​ใน code — พัฒนา​ร่วม​กับ Domain ExpertDomain Expertผู้เชี่ยวชาญ​ธุรกิจ​ที่​รู้​กฎ กระบวนการ และ​ความ​ต้องการ​ของ domain อย่าง​ลึกซึ้ง เป็น​แหล่ง​ความ​รู้​สำคัญ​ที่​ทีม​พัฒนา​ต้อง​ร่วม​งาน​ด้วย​อย่าง​ใกล้​ชิด​ใน DDDStrategic Design ผ่าน​วง​ป้อน​กลับ ไม่ใช่​ผ่าน​เอกสาร​ที่​ปกครอง​เหนือ​บทสนทนา
  • หนึ่ง​ทีม / 1 Bounded Context / 1 repository — ยัด​มาก​เกิน​ไป​โดย​ไม่มี​ขอบเขต​จะ​ได้ Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design
  • ท้าทาย​และ​รวม​ให้​เป็น​หนึ่ง ด้วย​คำถาม “อะไร​คือ core?” และ “ใคร?” เพื่อ​กลั่น Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design ที่​เล็ก​แต่​คม
  • Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ไม่​ผูก​กับ​สถาปัตยกรรม​เดียว — ใช้​คู่ Ports and AdaptersHexagonal Architectureสถาปัตยกรรม “Ports and Adapters” โดย Alistair Cockburn — วาง domain ไว้​ตรง​กลาง นิยาม port (interface) ให้ adapter ภายนอก​มา​เสียบ ทุก dependency ชี้​เข้าหา domainArchitecture, REST, Event-Driven, CQRSCQRSCommand Query Responsibility Segregation — แยก model สำหรับ “เขียน/แก้ไข” (command) ออก​จาก model สำหรับ “อ่าน” (query) เหมาะ​กับ domain ซับซ้อน แต่​เพิ่ม​ความ​ซับซ้อน ใช้​อย่าง​ระมัดระวังArchitecture, microservices ได้ แต่ domain model ต้อง​ปลอด​เทคโนโลยี

🔗 อ้างอิง​เพิ่มเติม​ใน DevIQ

เจาะ​ลึก​แนวคิด​ใน​บท​นี้​ต่อ​ได้ที่​คลัง​อ้างอิง DevIQ:

  • Bounded Context — นิยาม​และ​ตัวอย่าง​ของ “ขอบเขต​ของ​ภาษา” ที่​เป็น​แกน​หลัก​ของ​บท​นี้
  • Ubiquitous Language — ภาษา​กลาง​ที่​ทีม​และ Domain Expert พัฒนา​ร่วม​กัน​ภายใน Bounded Context
  • Domain และ Core Domain — ขยาย​ความ​ว่า Core Domain ต่าง​จาก subdomain อื่น​อย่างไร และ​ทำไม​ต้อง​กลั่น​ให้​เล็ก​และ​คม
  • Context Mapping — วิธี​เชื่อม​ความ​สัมพันธ์​ระหว่าง Bounded Context หลาย​อัน​ที่​บท​นี้​กล่าว​ถึง​ไว้
  • Event Storming — เทคนิค​เร่ง​ค้น​พบ scenario และ​ขอบเขต​ของ Bounded Context ที่​บท​นี้​แนะนำ​ให้​ลอง​ใช้​คู่​กัน

เช็กความเข้าใจ — บทที่ 2

ข้อ 1 / 4

คำว่า "Policy" ในงาน Underwriting, Claims, และ Inspections ควรถูกจัดการอย่างไรตามแนวทาง DDD?