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

Context Mapping — แผนที่​บริบท​ของ​ระบบ​จริง

ใน application ขนาด​ใหญ่​ที่​ซับซ้อน เรา​ไม่​ได้​มี Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design เพียง​ก้อน​เดียว — มี​หลาย model ใน​หลาย​บริบท​ทำงาน​ร่วม​กัน​เพื่อ​ตอบ​โจทย์​ของ​ระบบ บาง​บริบท​เป็น code เก่า (legacy) ของ​ทีม​อื่น บาง​บริบท​เป็น​บริการ​จาก​ภายนอก​ที่​ไม่รู้จัก​เรา​ด้วย​ซ้ำ ทีม​ที่ ไม่​เข้าใจ ว่า​ใน​ระบบ​มี​บริบท​อะไร​บ้าง​และ​แต่ละ​บริบท​สัมพันธ์​กัน​อย่างไร ย่อม​เสี่ยง​สูง​มาก​ที่​จะ​ทำลาย​ความ​ถูกต้อง​ของ model ตอน​เชื่อม​ต่อ​กัน เส้น​แบ่ง​ระหว่าง model จะ​พร่า​เลือน และ​ระบบ​จะ​กลาย​เป็น Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design อย่าง​รวดเร็ว

บท​นี้​ว่าด้วย Context MappingContext Mappingกิจกรรมการ​ระบุ Bounded Context และ​นิยาม​ความ​สัมพันธ์​ระหว่าง​กัน (เช่น Partnership, Shared Kernel, ACL) เพื่อ​จัดการ​การ​เชื่อม​ต่อ​ระหว่าง​ทีม/ระบบStrategic Design — กิจกรรมการ​วาด Context MapContext Mapแผนภาพ​ที่​แสดง Bounded Context ทั้งหมด​และ​ความ​สัมพันธ์​ระหว่าง​กัน ช่วย​ให้​เห็น​ภาพ​รวม​และ​จุด​เชื่อม​ต่อ/แปล​ภาษา​ใน​ระบบ​ใหญ่Strategic Design เพื่อ​จับ​ภาพ “ความ​เป็น​จริง” ของ​ภูมิทัศน์​ทั้ง​ระบบ ทั้ง​ด้าน​เทคนิค​และ​ด้าน​องค์กร แล้ว​ใช้​ความ​สัมพันธ์​ที่​หลากหลาย​แบบ (Anticorruption Layer, Shared Kernel, Customer/Supplier ฯลฯ) มา​จัดการ​การ​เชื่อม​ต่อ​ระหว่าง​ทีม​และ​ระหว่าง​บริบท​อย่าง​มี​สติ

หัวใจ​ของ​บท​นี้

Context Map ไม่ใช่​ภาพ “ระบบ​ใน​ฝัน” แต่​คือ​ภาพ ระบบ​ตาม​จริง​ใน​วัน​นี้ — รวม​ถึง​ส่วน​ที่​ยุ่งเหยิง ส่วน​ที่​ไม่มี​ใคร​เข้าใจ และ​ทิศทาง​ของ​อำนาจ​การ​ตัดสิน​ใจ​ระหว่าง​ทีม มัน​คือ​เครื่องมือ​เชิงกลยุทธ์​ที่​ช่วย​ให้​ทีม​มอง​เห็น​อันตราย​ล่วงหน้า ก่อน​ที่​ปัญหา​จะ​ลุกลาม​จน​กลาย​เป็น​ตัว​ขวาง​งาน (blocker)


หน้าที่​ของ Context MapContext Mapแผนภาพ​ที่​แสดง Bounded Context ทั้งหมด​และ​ความ​สัมพันธ์​ระหว่าง​กัน ช่วย​ให้​เห็น​ภาพ​รวม​และ​จุด​เชื่อม​ต่อ/แปล​ภาษา​ใน​ระบบ​ใหญ่Strategic Design คือ​ทำให้​ขอบเขต​ระหว่าง​บริบท​ต่างๆ ถูก​นิยาม​อย่าง​ชัดเจน และ​ทุก​ทีม​เข้าใจ “จุดสัมผัส” (contact point) ระหว่าง​กัน มัน​ไม่ใช่​เอกสาร​ละเอียด​ยิบ​ที่​วาด​ด้วย​เครื่องมือ enterprise architecture ราคา​แพง แต่​เป็น​ไดอะแกรม​ระดับ​สูง​ที่ วาด​ด้วย​มือ ได้ และ​เรียบ​ง่าย​พอที่​ทั้ง domain expert และ​นัก​พัฒนา​จะ​เข้าใจ​ร่วม​กัน

สิ่ง​สำคัญ​คือ นอกจาก​บริบท​ที่​เรา​เข้าใจ​ดีแล้ว แผนที่​ต้อง แสดง​ส่วน​ที่​ยัง​ไม่​เข้าใจ ด้วย เพื่อ​สะท้อน​สภาพ​อัน​ยุ่งเหยิง​ของ codebase ตาม​ที่​มัน​เป็น​จริง

รูปที่ 7-1: ตัวอย่าง Context Map — แต่ละบริบทมี model ของตัวเอง (Context A, Context B) เชื่อมกันผ่านจุดสัมผัส ส่วน Legacy Context เป็นก้อนรกที่หน้าตาเหมือน Big Ball of Mud ก็ถูกวาดไว้ตามจริง

Context Map มี​สอง​หน้า: ความ​จริง​เชิง​เทคนิค และ ความ​จริง​เชิง​องค์กร

ด้าน​เทคนิค​ของ​แผนที่​แสดง จุด​เชื่อม​ต่อ (integration point) ระหว่าง​บริบท เปรียบ​เหมือน “heat map” ที่​บอก​ทีม​ว่าการ​เปลี่ยนแปลง​ของ​พวก​เขา​จะ​กระทบ​เชิง​เทคนิค​ตรง​ไหน​บ้าง มัน​แสดง​ขอบเขต​ที่​มี​อยู่ และ​การ​แปล​ภาษา (translation) ที่​ใช้​รักษา​ความ​ถูกต้อง​ของ​แต่ละ Bounded Context เช่น บริบท​หนึ่ง​พึ่งพา​บริบท​ด้าน​การเงิน​ที่​ทีม​อื่น​ดูแล อีก​คู่​หนึ่ง​เชื่อม​กัน​ผ่าน​ฐาน​ข้อมูล​และ​ใช้ model ร่วม​กัน ส่วน​บริบท​ของ​บุคคล​ที่​สาม (third-party) เปิด​ให้​เข้าถึง​ผ่าน RESTful service

แผนที่​ต้อง​สะท้อน​ปัจจุบัน ไม่ใช่​อนาคต​ใน​อุดมคติ

Context Map ควร​เปลี่ยน เฉพาะ​เมื่อ code เปลี่ยน เหมือน​กับ Code ModelCode Modelmodel ใน code — การ​แสดงออก​ของ domain model ใน code จริง DDD ถือว่า code model คือ “การ​แสดงออก​หลัก” (primary expression) ของ domain model ไม่ใช่​ไดอะแกรม​หรือ​เอกสารStrategic Design และ Analysis ModelAnalysis Modelmodel เชิง​วิเคราะห์ — ภาพ​การ​ออกแบบ​เชิง​ตรรกะ​และ​โครงสร้าง​ของ​ซอฟต์แวร์​ที่​คน​ไม่ใช่​สาย​เทคนิค​ก็​เข้าใจ​ได้ (เช่น ภาพร่าง​หรือ UML) ใน DDD จะ​ถูก​ผูก​เข้า​กับ code model ผ่าน Ubiquitous LanguageStrategic Design ถ้า​วาด​เป็น​ภาพ “ระบบ​ที่​อยาก​ให้​เป็น” แทนที่​จะ​เป็น “ระบบ​ที่​เป็น​จริง” แผนที่​จะ​กลาย​เป็น​ภาพลวงตา​ที่​อันตราย​ยิ่ง​กว่า​ไม่มี​แผนที่​เลย — มัน​ต้อง​สะท้อน​ความ​จริง​ดิบๆ เท่านั้น​จึง​จะ​มี​ประโยชน์

การ​เปลี่ยนแปลง​กระบวนการ​ธุรกิจ​มัก​พาด​ผ่าน​หลาย Bounded Context การ​ประสาน​งาน​ระดับ​นี้​ต้องการ การ​บริหาร​ทีม พอๆ กับ​การ​เปลี่ยนแปลง​ทาง​เทคนิค เรา​ต้อง​รู้​ว่า​ใคร​รับผิดชอบ​บริบท​ไหน และ​การ​เปลี่ยน​จะ​เกิด​ขึ้น​ได้​อย่างไร จุด​แข็งข้อ​หนึ่ง​ที่ Context Map เหนือ​กว่า​ไดอะแกรม UML ทั่วไป​คือ มัน​แสดง ทิศ​ของ​ความ​สัมพันธ์​ระหว่าง​ทีม ได้ — ทีม​ที่​อยู่​คนละ project อาจ​ต้อง​จูน release schedule และ​ลำดับ​ความ​สำคัญ​ให้​ตรง​กัน ถ้า​ไม่​เข้าใจ “การเมือง​องค์กร” ตรง​นี้ การ​เปลี่ยนแปลง​บริบท​ของ​ทีม​อื่น​อาจ​ล่าช้า​หรือ​ไม่​เกิด​ขึ้น​เลย

วาด​เฉพาะ​ความ​จริง​ที่​เกี่ยวข้อง​กับ​เรา

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


รูปแบบ​ความ​สัมพันธ์​ต่อ​ไป​นี้​บอกว่า model และ​ทีม​สัมพันธ์​กัน​อย่างไร — มัน​ไม่ใช่ pattern เชิง​เทคนิค​ของ​การ​สื่อสาร​ข้าม​บริบท (เรื่อง​นั้น​เป็น​ของ Part II ใน​หนังสือ) แต่​เป็น “ภูมิรัฐศาสตร์” (geopolitics) ของ​ระบบ

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

รูปที่ 7-4: ใช้ Anticorruption Layer ห่อหุ้มการสื่อสารกับ code ที่เราไม่ได้เป็นเจ้าของหรือแก้ไม่ได้ ชั้นนี้บรรจุ “เฉพาะตรรกะการแปลภาษา” ไม่มี business logic

ACL ทำงาน​คล้าย adapter patternAdapterตัว​ที่ “ทำให้” port เป็น​จริง เช่น PostgresCargoRepository หรือ REST controller อยู่​ชั้น​นอก​และ​พึ่งพา domain ทำให้​สลับ​เทคโนโลยี​ได้​โดย​ไม่​แตะ domainArchitecture — มัน​แปลง API ของ​อีก​บริบท​ให้​กลาย​เป็น API ที่​เรา​ทำงาน​ด้วย​ได้ ประโยชน์​สำคัญ​คือ​ใช้​กับ legacy หรือ third-party ที่​เรา​แก้ API ไม่​ได้ และ​เป็น เทคนิค refactoring ที่​ดี​มาก: เมื่อ​ต้อง​เพิ่ม feature ลง​ใน​ระบบ​ที่​เป็น Big Ball of Mud แทนที่​จะ “เพิ่ม​ความ​ยุ่งเหยิง​เข้าไป​อีก” หรือ “เขียน​ใหม่​ทั้ง​ระบบ” (ซึ่ง​ทั้ง​คู่​ล้วน​เสี่ยง​และ​กิน​เวลา) เรา​ใช้ ACL กั้น​บริบท​ใหม่​ออก​จาก code เก่า​ที่​ยุ่งเหยิง แล้ว​สร้าง​ขอบเขต​ที่​ชัดเจน​ได้​โดย​ไม่​ต้อง​ไป​แตะ​ต้อง​ความ​ยุ่งเหยิง​เดิม

🚢 ตัวอย่าง​ขนส่ง — ACL กับ​ระบบ​จัด​ตาราง​เรือ​เก่า

สมมุติ Bounded Context Routing ของ​เรา (วาง ItineraryItineraryValue Object ที่​เป็น “แผนการ​เดินทาง​จริง” ของ Cargo ประกอบ​ด้วย​ลำดับ​ของ Leg (ช่วง​การ​ขนส่ง​แต่ละ​ช่วง)Tactical Design ให้ Cargo) ต้อง​ดึง​ตาราง​เดิน​เรือ​จาก​ระบบ scheduling เก่า​ที่​เขียน​ไว้​สิบ​ปี​ก่อน ระบบ​เก่า​มอง​โลก​เป็น​ตาราง VOYAGE_TBL กับ​รหัส​ท่าเรือ​แบบ legacy

แทนที่​จะ​ให้​คำ​ว่า VoyageRow ไหล​เข้า​มา​ปน​กับ model Routing ที่​สะอาด​ของ​เรา เรา​สร้าง ACL ที่​รับ​ข้อมูล​ดิบ​จาก​ระบบ​เก่า​แล้ว​แปลง​เป็น CarrierMovement และ Location ใน​ภาษา​ของ​เรา ผล​คือ​ถ้า​ระบบ​เก่า​เปลี่ยน column ก็​แก้​แค่​ใน ACL — model core ของ Routing ไม่​สะเทือน

ถ้า​สอง​ทีม​ทำงาน​ใกล้​ชิด​ใน app เดียวกัน บน2 Bounded Context ที่​มี​แนวคิด​และ​ตรรกะ domain ทับซ้อน​กัน​มาก ภาระ​ของ​การ​แยก​ทีม​และ​แปล​ภาษา​ไป​มา​อาจ​ไม่​คุ้ม ทาง​เลือก​คือ​ร่วมมือ​กัน แบ่ง model บาง​ส่วน​มา​ใช้​ร่วม — ส่วน​ที่ share นี้​เรียก​ว่า Shared KernelShared Kernelสอง​ทีม​ตกลง​แบ่ง model ส่วน​เล็ก ๆ มา​ใช้​ร่วม​กัน​โดย​มี​ขอบเขต​ชัดเจน ส่วน​นี้​ห้าม​แก้​โดย​ไม่​ปรึกษา​กัน เพราะ​กระทบ​ทั้ง​สอง​ฝ่ายStrategic Design เหมาะ​มาก​เมื่อ​สอง​บริบท​อยู่​ใน SubdomainSubdomainส่วน​ย่อย​ของ Domain ใหญ่ เช่น Domain e-commerce แตก​เป็น subdomain การ​สั่ง​ซื้อ การ​ชำระ​เงิน คลัง​สินค้า ฯลฯ อยู่​ใน “พื้นที่​ปัญหา” (problem space)Strategic Design เดียวกัน​และ​ใช้​ตรรกะ domain ชุด​ย่อย​ร่วม​กัน

รูปที่ 7-5: การเชื่อมต่อด้วย Shared Kernel — model Employee เป็นของร่วมกันทั้ง Payroll Context และ HR Context จึงถูก share เป็นแกนกลาง

Shared Kernel เสี่ยง​เพราะ coupling แน่น​ขึ้น

เพราะ​มี dependency บน code ร่วม​กัน ทีม​หนึ่ง​อาจ​ทำ​ระบบ​อีก​ทีม​พัง​ได้​ง่ายๆ ทุก​คนใน​ทั้ง​สอง​ทีม​ต้อง​เข้าใจ​ข้อ​นี้ และ​ต้อง​มี​ระบบ continuous integration ที่​รัน test ตรวจ​พฤติกรรม​ของ ทั้ง2 model ทุก​ครั้ง​ที่​แก้ model ส่วนร่วม หาก​เลือก​ใช้ Shared Kernel แนะนำ​ให้​ดำเนิน​การ​ใน​รูปแบบ Partnership

ปกติ​ทุก​ระบบ​ที่มา​คุย​กับ​เรา​ต้อง​มี​ชั้น​แปลง​ภาษา​ของ​ตัวเอง (คล้าย ACL) เพื่อ​แปลง model เรา​ให้​เป็น​ของ​เขา แต่​ถ้า ผู้บริโภค​หลาย​ราย​ต้อง​แปลง​เห​มือ​นๆ กัน ก็​เปลือง​แรง​ซ้ำซ้อน ทาง​ที่​ดี​กว่า​คือ​ให้​บริบท​ต้นทาง​เปิด​ชุด​บริการ​ที่​เผย​ความ​สามารถ​ของ​ตน​ผ่าน สัญญา (contract) ที่​นิยาม​ไว้​ชัดเจน — นี่​คือ Open Host ServiceOpen Host Service (OHS)ทีม​ต้นน้ำ​เปิด​บริการ​เป็น​โพรโทคอล/API ที่​นิยาม​ไว้​ชัดเจน ให้​ทุก​คน​ที่​ต้อง​เชื่อม​ต่อ​มา​ใช้ได้ เหมาะ​กับ​ระบบ​ที่​มี​ผู้​ใช้​หลาย​ฝ่ายStrategic Design (OHS)

รูปที่ 7-7: การเชื่อมต่อด้วย Open Host Service — Order Management เปิด public API ผ่านสัญญาที่ใช้ model แบบย่อ ฝั่งผู้บริโภค (Commerce, Procurement, CRM) ไม่ต้องแปลภาษาเองอีกต่อไป

OHS มัก​จับ​คู่​กับ Published LanguagePublished Languageภาษา​กลาง​ที่​จัด​ทำ​เป็น​เอกสาร​ชัดเจน ใช้​เป็น​สื่อ​แลกเปลี่ยน​ข้อมูล​ระหว่าง context เช่น มาตรฐาน​ข้อมูล​ของ​อุตสาหกรรม มัก​ใช้​คู่​กับ OHSStrategic Design — ภาษา​กลาง​ที่​จัด​ทำ​เป็น​เอกสาร​ชัดเจน เช่น model sales order แบบ​ย่อ​ที่​ทุก​ฝ่าย​เข้าใจ​ตรง​กัน เมื่อ​ต้นทาง​เปิด​เป็น OHS + Published Language ผู้บริโภค​ก็​ไม่​ต้อง​ต่าง​คน​ต่าง​เขียน ACL แปลง model ที่​ซับซ้อน​ของ Order Management อีก​ต่อ​ไป

ถ้า​ค่า​ใช้​จ่าย​ของ​การ​เชื่อม​ต่อ​สูง​เกิน​ไป ไม่​ว่าด้วย​ความ​ซับซ้อน​ทาง​เทคนิค​หรือ​ทางการเมือง ก็​อาจ​ตัดสิน​ใจ ไม่​เชื่อม​เลย แล้ว​ให้​แต่ละ​ทีม​ทำ​แยก​กัน — นี่​คือ Separate WaysSeparate Waysประกาศ​ว่า Bounded Context นี้​ไม่​เชื่อม​ต่อ​กับ​อัน​อื่น​เลย เพื่อ​ให้​แต่ละ​ฝ่าย​หา​ทาง​แก้​แบบ​ง่าย ๆ เฉพาะ​ของ​ตน ใช้​เมื่อ​ค่า​ใช้​จ่าย​การ​เชื่อม​ต่อ​ไม่​คุ้มStrategic Design การ​เชื่อม​ต่อ​อาจ​ทำ​ผ่าน UI หรือ​กระบวนการ​มือ​แทน เช่น app customer service ที่​อยาก​โชว์​ออเดอร์​ค้าง​ของ​ลูกค้า แต่​ถ้า​การ integrate กับ Order Management แพง​เกิน​ไป ก็​แค่​ใส่​เมนู link เปิด Order Management ขึ้น​มา​อีก​หน้า​จอ ผู้​ใช้ได้​ข้อมูล​ที่​ต้องการ​โดย​ไม่​ต้อง​แบก​ความ​ซับซ้อน​ของ​การ​เชื่อม​ต่อ​แบบ​เต็ม​รูปแบบ (แลก​กับ feature ที่​ลด​ลง​เล็กน้อย)


ความ​สัมพันธ์​ระหว่าง Bounded Context นิยาม​ได้​ด้วย ทิศ ปลาย​หนึ่ง​เป็น upstream อีก​ปลาย​เป็น downstream ถ้า​คุณ​เป็น​ฝั่ง downstream คุณ​ย่อม พึ่งพา ข้อมูล​หรือ​พฤติกรรม​ของ​ฝั่ง upstream — ถ้า interface ของ upstream เปลี่ยน ฝั่ง​บริโภค downstream ก็​ต้อง​เปลี่ยน​ตาม และ release plan ของ upstream ก็​ส่ง​อิทธิพล​ต่อ downstream ด้วย Upstream/DownstreamUpstream / Downstreamความ​สัมพันธ์​ที่​การกระทำ​ของ​ฝ่าย​ต้นน้ำ (upstream) ส่ง​ผล​ต่อ​ฝ่าย​ปลาย​น้ำ (downstream) แต่​ไม่ใช่​ใน​ทาง​กลับ​กัน — ทิศ​ของ​อิทธิพลStrategic Design จึง​เป็น “ทิศ​ของ​อิทธิพล” pattern สอง​ตัว​ต่อ​ไป​นี้​จำแนก​ความ​สัมพันธ์​นี้

ถ้า​สอง​ทีม​ดูแล​คนละ​บริบท​แต่​มุ่ง​สู่​เป้าหมาย​เดียวกัน ก็​ตั้ง PartnershipPartnershipสอง​ทีม​ที่​หาก​ฝ่าย​ใด​ล้มเหลว​อีก​ฝ่าย​ก็​ส่ง​งาน​ไม่​ได้ จึง​ต้อง​วางแผน​และ​จัดการ​การ​เชื่อม​ต่อ​ร่วม​กัน feature ที่​พึ่งพา​กัน​ถูก​จัด​ให้​เสร็จ​ใน release เดียวกันStrategic Design เพื่อ​ร่วมมือ​กัน​บน​การ​เชื่อม​ต่อ​ได้ ความ​ร่วมมือ​ครอบคลุม​ทั้ง interface ทาง​เทคนิค​ที่​ตอบ​โจทย์​ทั้ง​สอง​ฝ่าย และ​ใน​เชิง​การเมือง release ของ​ทั้ง​สอง​ทีม​จะ​ถูก​จัด​ให้​ตรง​กัน​เพื่อ​ให้ interface และ​จุดสัมผัส​ที่​จำเป็น​ออก​พร้อม​กัน​ใน​เวลา​ที่​ต้อง​ใช้ (ถ้า​ใช้ Shared Kernel ร่วม​กัน แนะนำ​ให้​ทำ​ใน​ฐานะ Partnership)

เมื่อ​ทีม​ไม่​ได้​มุ่ง​สู่​เป้าหมาย​เดียวกัน เพื่อ​กัน​ไม่​ให้​ทีม upstream ตัดสิน​ใจ​ฝ่าย​เดียว​จน​กระทบ​ทั้ง project เรา​ตั้ง​ความ​สัมพันธ์​แบบ Customer/SupplierCustomer / Supplierความ​สัมพันธ์​ที่​ทีม​ต้นน้ำ (supplier) รับ​ความ​ต้องการ​ของ​ทีม​ปลาย​น้ำ (customer) เข้าไป​วางแผน​ด้วย มี​การ​เจรจา​และ​จัด​ลำดับ​งาน​ให้​ชัดเจนStrategic Design ที่​ร่วมมือ​กัน​มาก​ขึ้น ทั้ง​สอง​ทีม​ตกลง interface ร่วม​ที่​พอใจ​ทั้ง​ด้าน​เทคนิค​และ​ตาราง​เวลา ฝั่ง customer คือ downstream — customer จะ​เข้า​ร่วม​ประชุม​วางแผน​ของ supplier (upstream) เพื่อ​ให้​ความ​ต้องการ​ของ​ตน​ถูก​เข้าใจ และ​มอง​เห็น​ล่วงหน้า​เมื่อ upstream กำลัง​จะ​เปลี่ยน

🛒 ตัวอย่าง e-commerce — Customer/Supplier ระหว่าง Commerce กับ Order Management

Bounded Context Commerce (ตะกร้า/เช็ก​เอาต์) เป็น downstream ของ Order Management ที่​จัดการ​สถานะ​ออเดอร์​หลัง​การ​ขาย วัน1 Commerce ต้องการ field “วัน​ที่​จัด​ส่ง​โดย​ประมาณ” ที่ Order Management ยัง​ไม่​ได้​เปิด​ให้

ถ้า​เป็น Customer/Supplier: ทีม Commerce เข้าไป​นั่ง​ใน​ที่​ประชุม sprint ของ Order Management เพื่อ​ขอ​ให้​บรรจุ field นี้​เข้า​แผน ทั้ง​สอง​ตกลง interface และ release ร่วม​กัน — ไม่มี​ใคร​ถูก block เพราะ​รอ​กัน​เฉยๆ

ข้อ​ควร​ระวัง: เพราะ​ร่วมมือ​กัน​มาก​ขึ้น การ​ตัดสิน​ใจ​อาจ​ช้า​ลง ต้อง​ประชุม/คุย​กัน​บ่อย ถ้า​ทีม​อยู่​คนละ time zone หรือ​มี​ภาระ​งาน​ล้น​มือ ค่า overhead ของ​การ​ประสาน​งาน​อาจ​ทำให้​ล่าช้า​ยืดเยื้อ การ​วางแผน​ล่วงหน้า​และ​ตกลง​เงื่อนไข​ไว้​ก่อน​จะ​ช่วย​ลด​การ​ขวาง​งาน (blocking) ซึ่ง​กัน​และ​กัน

ถ้า upstream ไม่​ยอม​ร่วมมือ ฝั่ง downstream ก็​จำ​ต้อง “ยอม​ตาม” model ของ upstream ตอน​เชื่อม​ต่อ — นี่​คือ ConformistConformistทีม​ปลาย​น้ำ​ยอม “ตามใจ” model ของ​ทีม​ต้นน้ำ​ทั้งหมด​เพื่อ​ตัด​ความ​ซับซ้อน​ใน​การ​แปล​ภาษา ใช้​เมื่อ​ทีม​ต้นน้ำ​ไม่มี​แรง​จูงใจ​จะ​รองรับ​เราStrategic Design ที่​พบ​บ่อย​ที่สุด​คือ​การ​เชื่อม​กับ supplier ภายนอก เช่น payment provider ซึ่ง​แทบ​จะ​ไม่มี​ทาง​เปลี่ยน API ให้​คุณ เว้น​แต่​คุณ​จะ​เป็น​ลูกค้า​ราย​ใหญ่ ถ้า​คุณ​เป็น downstream ที่​ตั้ง Customer/Supplier ไม่​ได้ และ​การ​ทำ ACL ก็​แพง​เกิน​ไป การ​ยอม​ตาม model ของ provider จะ​ทำให้ integration ง่าย​ขึ้น

ราคา​ของ​การ​เป็น Conformist

ข้อ​เสียชัดๆ คือ​ทีม downstream อาจ​ต้อง เสีย​ความ​ชัดเจน​ของ domain model ตัวเอง เพราะ​ต้อง​จัด​ให้​ตรง​กับ model ของ upstream แม้​แนวคิด​จะ​ต่าง​จาก​มุมมอง​ของ​เรา​ก็ตาม ทาง​เลือก​ที่​ดี​กว่า​ถ้า​พอ​จ่าย​ไหว​คือ​ใช้ Anticorruption LayerAnticorruption Layer (ACL)ชั้น​กั้น​ที่​ทีม​ปลาย​น้ำ​สร้าง​ขึ้น​เพื่อ​แปลง model ของ​ระบบ​อื่น​ให้​เป็น​ภาษา​ของ model ตัวเอง ป้องกัน​ไม่​ให้ model ภายนอก​มา “ปน​เปื้อน” model เราStrategic Design มา​กั้น เพื่อ​ให้การ​เปลี่ยนแปลง​ที่​จุดสัมผัส​ไม่​ลาม​เข้า model ภายใน


เวลา​วาด Context Map เรา​เขียน ประเภท​ความ​สัมพันธ์​เชิง​องค์กร และ ประเภท​การ​เชื่อม​ต่อ​เชิง​เทคนิค ลง​บน​เส้น​ที่​เชื่อม​สอง​บริบท พร้อม​ระบุ​ว่า​ฝั่ง​ไหน upstream ฝั่ง​ไหน downstream ด้วย​ตัว​อักษร​หรือ​สัญลักษณ์

รูปที่ 7-9: Context Map ที่ติดป้ายประเภทการเชื่อมต่อครบ — Commerce เป็น Customer/Supplier (downstream, มี ACL) ต่อ Order Management ที่เปิด Open Host, Order Management เป็น Conformist ต่อ Payment Gateway, และ Commerce กับ CRM เป็น Partnership ที่ share Shared Kernel (Customer Model)

ลอง​อ่าน​แผนที่​นี้​เป็น​ไดอะแกรม​สรุป​ความ​สัมพันธ์:

flowchart LR
  PG[Payment Gateway Context]
  OM[Order Management Context]
  CM[Commerce Context]
  CRM[CRM Context]

  OM -- "Open Host / Customer-Supplier" --> CM
  OM -. "Conformist (OM ยอมตาม)" .-> PG
  CM -- "Partnership + Shared Kernel: Customer Model" --- CRM

  classDef ctx fill:#eef4ff,stroke:#3b6fb5,color:#1a3a5c;
  class PG,OM,CM,CRM ctx;

ใน​หลาย​แง่ การ​สื่อสาร​ระหว่าง​บริบท (ทั้ง​เทคนิค​และ​องค์กร) สำคัญ​ต่อ​ทีม​ที่​กำลัง​เริ่ม project ยิ่ง​กว่า​ตัว Bounded Context เอง เสีย​อีก Context Map เป็น artifact ทรง​พลัง​ที่​พา​คน​ใหม่​เข้าใจ​ระบบ​ได้​อย่าง​รวดเร็ว และ​เป็น​สัญญาณ​เตือน​ภัย​ล่วงหน้า​ถึง​จุด​ที่​อาจ​มี​ปัญหา ประโยชน์​เชิงกลยุทธ์​ที่​สำคัญ​มี​ดังนี้:

  • รักษา​ความ​ถูกต้อง (integrity) — ทุก​ทีม​ต้อง​เข้าใจ​แผนที่ ไม่​ต้อง​รู้ไส้​ใน​ของ​แต่ละ​บริบท แต่​ต้อง​รู้​ว่า​มี​บริบท​อื่น​อยู่ รู้ API ที่​มัน​เปิด รู้ความ​สัมพันธ์ และ​ที่​สำคัญ​สุด​คือ​รู้​ว่า​มัน​รับผิดชอบ​แนวคิด​อะไร เพื่อ​กัน​ไม่​ให้​เส้น​ความ​รับผิดชอบ​เบลอ code ที่​โฟกัส model เดียว​จะ “ยืดหยุ่น” (supple) เพราะ​การ​เปลี่ยน​กระทบ​แค่​บริบท​เดียว ไม่​ลาม​ทั้ง domain
  • เป็น​พื้นฐาน​ของ​แผนการ​รบ — แผนที่​ชี้​ว่า​ส่วน​ไหน​ยุ่งเหยิง ส่วน​ไหน​คือ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design ส่วน​ที่ “เกิน​เยียวยา” ก็​กัน​แยก​ไว้ ส่วน​ที่​ไม่มี​ความ​ได้​เปรียบ​เชิงกลยุทธ์​ก็​ไม่​จำเป็น​ต้อง​ลงทุน​ทำ Ubiquitous Language ขณะ​ที่​ส่วน​ที่​เป็น core หรือ​ซับซ้อน​คือ​ผู้​สมควร​แก่​การ​ทำ tactical DDD และ​ต้อง​กัน​ให้​ห่าง​จาก​บริบท​ที่​ออกแบบ​ไม่​ดี
  • เข้าใจความ​เป็น​เจ้าของ​และ​ความ​รับผิดชอบ — Context Mapping คือ​การ​สืบสวน​และ​ทำให้​ชัด คุณ​อาจ​วาด​แผน​ที่ชัดๆ ไม่​ได้​ใน​ทันที แต่ กระบวนการ ของ​การ​ชี้​ชัด​ว่า​ใคร​รับผิดชอบ​อะไร สำคัญพอๆ กับ artifact ที่​เสร็จ​แล้ว
  • เผย​จุด​สับสน​ใน​กระบวนการ​ธุรกิจ (business process) — กระบวนการ​ที่​คาบเกี่ยว​ระหว่าง​บริบท​มัก​ตก​อยู่​ใน “แดน​ไร้​เจ้าของ” แผนที่​ช่วย​เผย​ขั้นตอน​ทาง​ธุรกิจ​ที่​ขาดตอน​หรือ​เสื่อมถอย​ไป​ตาม​กาล​เวลา ซึ่ง​มัก​มี​คุณค่า​ต่อ​ฝั่ง​ธุรกิจ​มากกว่า​ฝั่ง​เทคนิค​เสีย​อีก
  • ระบุ​อุปสรรค​ที่​ไม่ใช่​เชิง​เทคนิค — แผนที่​เผย​ขอบเขต​ระหว่าง​แผนก ถ้า​ทีม​คุณ​ไม่​ได้​เป็น​เจ้าของ​ทุก​บริบท ก็​ต้อง​ประสาน​เรื่อง release scheduling ล่วงหน้า​ก่อน​ที่​มัน​จะ​กลาย​เป็น​ตัว​ขวาง​งาน (blocker)
  • ส่งเสริม​การ​สื่อสาร​ที่​ดี & ช่วย​พนักงาน​ใหม่ — เมื่อ​แผนที่​บอกว่า​บริบท​คุณ​เชื่อม​กับ​บริบท​อื่น คุณ​ก็​รู้ทันที​ว่า​ต้อง​ไป​คุย​กับ​ทีม​ไหน และ​ถ้า​คุณ​เป็น​ฝั่ง upstream คุณ​ก็​รู้​ว่า​หน้าที่​ของ​คุณ​คือ​นำ​การ​ตัดสิน​ใจ​และ​มัก​ต้อง​เป็น​ฝ่าย​เริ่ม​สื่อสาร
สรุป​แก่น​ของ Context Mapping

จำ pattern หลัก​ให้​ครบ: ACL กั้น​ไม่​ให้ model ภายนอก​มา​ปน​เปื้อน model เรา · Shared Kernel สำหรับ​บริบท​ที่​ทับซ้อน​กัน​และ​ใช้ model ร่วม​กัน · Open Host Service เปิด API กลาง (มัก​จับ​คู่​กับ Published Language) แทน​การ​ให้​ทุก​คน​แปล​ภาษา​เอง · Upstream/Downstream คือ​ทิศทาง​ของ​อิทธิพล · Customer/Supplier = downstream ที่​ร่วมมือ​กับ upstream · Conformist = upstream ไม่​ร่วมมือ downstream จึง​ต้อง​ยอม​ตาม (บ่อย​ครั้ง​คือ third-party) · Partnership = สอง​ทีม​ที่​มุ่ง​สู่​เป้าหมาย​เดียวกัน · Separate Ways = เชื่อม​ต่อ​แพง​เกิน​ไป​จน​เลือก​ที่​จะ​ไม่​เชื่อม​เลย


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

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

  • Context Mapping — สรุป​แนวคิด Context Map และ​รูปแบบ​ความ​สัมพันธ์​ระหว่าง​บริบท​แบบ​กระชับ ต่อยอด​จาก​เนื้อหา​บท​นี้​ได้​ทันที
  • Bounded Context — ทบทวน​ว่า Bounded Context คือ​อะไร ก่อน​จะ​เข้าใจ​ว่า​ทำไม​ต้อง​มี​แผนที่​เชื่อม​ระหว่าง​มัน
  • Anticorruption Layer — อธิบาย​ชั้น​แปล​ภาษา​ที่​กัน model ปน​เปื้อน ตรง​กับ​หัวข้อ ACL ใน​บท​นี้
  • Shared Kernel — ขยาย​ความ​รูปแบบ​การ​แบ่ง model ร่วม​กัน​ระหว่าง​สอง​บริบท​ที่​ทับซ้อน​กัน
  • Strategic Design — มุมมอง​ภาพ​ใหญ่​ว่า Context Mapping เป็น​เครื่องมือ​เชิงกลยุทธ์​ระดับ​องค์กร​อย่างไร

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

ข้อ 1 / 4

Context Map ที่ดีควรแสดงอะไร?