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

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 กับบริบทอื่นช่วยให้เข้าใจตำแหน่งและความสำคัญของมันในภาพรวมขององค์กร
รู้จักความสัมพันธ์ระหว่าง Bounded Context
หัวข้อที่มีชื่อว่า “รู้จักความสัมพันธ์ระหว่าง Bounded Context”รูปแบบความสัมพันธ์ต่อไปนี้บอกว่า model และทีมสัมพันธ์กันอย่างไร — มันไม่ใช่ pattern เชิงเทคนิคของการสื่อสารข้ามบริบท (เรื่องนั้นเป็นของ Part II ในหนังสือ) แต่เป็น “ภูมิรัฐศาสตร์” (geopolitics) ของระบบ
Anticorruption Layer — ชั้นกัน model ปนเปื้อน
หัวข้อที่มีชื่อว่า “Anticorruption Layer — ชั้นกัน model ปนเปื้อน”เมื่อต้องเชื่อมกับ 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)

ACL ทำงานคล้าย adapter patternAdapterตัวที่ “ทำให้” port เป็นจริง เช่น PostgresCargoRepository หรือ REST controller อยู่ชั้นนอกและพึ่งพา domain ทำให้สลับเทคโนโลยีได้โดยไม่แตะ domainArchitecture — มันแปลง API ของอีกบริบทให้กลายเป็น API ที่เราทำงานด้วยได้ ประโยชน์สำคัญคือใช้กับ legacy หรือ third-party ที่เราแก้ API ไม่ได้ และเป็น เทคนิค refactoring ที่ดีมาก: เมื่อต้องเพิ่ม feature ลงในระบบที่เป็น Big Ball of Mud แทนที่จะ “เพิ่มความยุ่งเหยิงเข้าไปอีก” หรือ “เขียนใหม่ทั้งระบบ” (ซึ่งทั้งคู่ล้วนเสี่ยงและกินเวลา) เราใช้ ACL กั้นบริบทใหม่ออกจาก code เก่าที่ยุ่งเหยิง แล้วสร้างขอบเขตที่ชัดเจนได้โดยไม่ต้องไปแตะต้องความยุ่งเหยิงเดิม
สมมุติ 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 ไม่สะเทือน
Shared Kernel — แบ่ง model ส่วนเล็กมาใช้ร่วมกัน
หัวข้อที่มีชื่อว่า “Shared Kernel — แบ่ง model ส่วนเล็กมาใช้ร่วมกัน”ถ้าสองทีมทำงานใกล้ชิดใน app เดียวกัน บน2 Bounded Context ที่มีแนวคิดและตรรกะ domain ทับซ้อนกันมาก ภาระของการแยกทีมและแปลภาษาไปมาอาจไม่คุ้ม ทางเลือกคือร่วมมือกัน แบ่ง model บางส่วนมาใช้ร่วม — ส่วนที่ share นี้เรียกว่า Shared KernelShared Kernelสองทีมตกลงแบ่ง model ส่วนเล็ก ๆ มาใช้ร่วมกันโดยมีขอบเขตชัดเจน ส่วนนี้ห้ามแก้โดยไม่ปรึกษากัน เพราะกระทบทั้งสองฝ่ายStrategic Design เหมาะมากเมื่อสองบริบทอยู่ใน SubdomainSubdomainส่วนย่อยของ Domain ใหญ่ เช่น Domain e-commerce แตกเป็น subdomain การสั่งซื้อ การชำระเงิน คลังสินค้า ฯลฯ อยู่ใน “พื้นที่ปัญหา” (problem space)Strategic Design เดียวกันและใช้ตรรกะ domain ชุดย่อยร่วมกัน

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

OHS มักจับคู่กับ Published LanguagePublished Languageภาษากลางที่จัดทำเป็นเอกสารชัดเจน ใช้เป็นสื่อแลกเปลี่ยนข้อมูลระหว่าง context เช่น มาตรฐานข้อมูลของอุตสาหกรรม มักใช้คู่กับ OHSStrategic Design — ภาษากลางที่จัดทำเป็นเอกสารชัดเจน เช่น model sales order แบบย่อที่ทุกฝ่ายเข้าใจตรงกัน เมื่อต้นทางเปิดเป็น OHS + Published Language ผู้บริโภคก็ไม่ต้องต่างคนต่างเขียน ACL แปลง model ที่ซับซ้อนของ Order Management อีกต่อไป
Separate Ways — แยกกันเดิน
หัวข้อที่มีชื่อว่า “Separate Ways — แยกกันเดิน”ถ้าค่าใช้จ่ายของการเชื่อมต่อสูงเกินไป ไม่ว่าด้วยความซับซ้อนทางเทคนิคหรือทางการเมือง ก็อาจตัดสินใจ ไม่เชื่อมเลย แล้วให้แต่ละทีมทำแยกกัน — นี่คือ Separate WaysSeparate Waysประกาศว่า Bounded Context นี้ไม่เชื่อมต่อกับอันอื่นเลย เพื่อให้แต่ละฝ่ายหาทางแก้แบบง่าย ๆ เฉพาะของตน ใช้เมื่อค่าใช้จ่ายการเชื่อมต่อไม่คุ้มStrategic Design การเชื่อมต่ออาจทำผ่าน UI หรือกระบวนการมือแทน เช่น app customer service ที่อยากโชว์ออเดอร์ค้างของลูกค้า แต่ถ้าการ integrate กับ Order Management แพงเกินไป ก็แค่ใส่เมนู link เปิด Order Management ขึ้นมาอีกหน้าจอ ผู้ใช้ได้ข้อมูลที่ต้องการโดยไม่ต้องแบกความซับซ้อนของการเชื่อมต่อแบบเต็มรูปแบบ (แลกกับ feature ที่ลดลงเล็กน้อย)
ความสัมพันธ์เชิงทิศทาง: Upstream / Downstream
หัวข้อที่มีชื่อว่า “ความสัมพันธ์เชิงทิศทาง: Upstream / Downstream”ความสัมพันธ์ระหว่าง Bounded Context นิยามได้ด้วย ทิศ ปลายหนึ่งเป็น upstream อีกปลายเป็น downstream ถ้าคุณเป็นฝั่ง downstream คุณย่อม พึ่งพา ข้อมูลหรือพฤติกรรมของฝั่ง upstream — ถ้า interface ของ upstream เปลี่ยน ฝั่งบริโภค downstream ก็ต้องเปลี่ยนตาม และ release plan ของ upstream ก็ส่งอิทธิพลต่อ downstream ด้วย Upstream/DownstreamUpstream / Downstreamความสัมพันธ์ที่การกระทำของฝ่ายต้นน้ำ (upstream) ส่งผลต่อฝ่ายปลายน้ำ (downstream) แต่ไม่ใช่ในทางกลับกัน — ทิศของอิทธิพลStrategic Design จึงเป็น “ทิศของอิทธิพล” pattern สองตัวต่อไปนี้จำแนกความสัมพันธ์นี้
Partnership — หุ้นส่วนสู่เป้าหมายร่วม
หัวข้อที่มีชื่อว่า “Partnership — หุ้นส่วนสู่เป้าหมายร่วม”ถ้าสองทีมดูแลคนละบริบทแต่มุ่งสู่เป้าหมายเดียวกัน ก็ตั้ง PartnershipPartnershipสองทีมที่หากฝ่ายใดล้มเหลวอีกฝ่ายก็ส่งงานไม่ได้ จึงต้องวางแผนและจัดการการเชื่อมต่อร่วมกัน feature ที่พึ่งพากันถูกจัดให้เสร็จใน release เดียวกันStrategic Design เพื่อร่วมมือกันบนการเชื่อมต่อได้ ความร่วมมือครอบคลุมทั้ง interface ทางเทคนิคที่ตอบโจทย์ทั้งสองฝ่าย และในเชิงการเมือง release ของทั้งสองทีมจะถูกจัดให้ตรงกันเพื่อให้ interface และจุดสัมผัสที่จำเป็นออกพร้อมกันในเวลาที่ต้องใช้ (ถ้าใช้ Shared Kernel ร่วมกัน แนะนำให้ทำในฐานะ Partnership)
Customer/Supplier — ลูกค้ากับซัพพลายเออร์
หัวข้อที่มีชื่อว่า “Customer/Supplier — ลูกค้ากับซัพพลายเออร์”เมื่อทีมไม่ได้มุ่งสู่เป้าหมายเดียวกัน เพื่อกันไม่ให้ทีม upstream ตัดสินใจฝ่ายเดียวจนกระทบทั้ง project เราตั้งความสัมพันธ์แบบ Customer/SupplierCustomer / Supplierความสัมพันธ์ที่ทีมต้นน้ำ (supplier) รับความต้องการของทีมปลายน้ำ (customer) เข้าไปวางแผนด้วย มีการเจรจาและจัดลำดับงานให้ชัดเจนStrategic Design ที่ร่วมมือกันมากขึ้น ทั้งสองทีมตกลง interface ร่วมที่พอใจทั้งด้านเทคนิคและตารางเวลา ฝั่ง customer คือ downstream — customer จะเข้าร่วมประชุมวางแผนของ supplier (upstream) เพื่อให้ความต้องการของตนถูกเข้าใจ และมองเห็นล่วงหน้าเมื่อ upstream กำลังจะเปลี่ยน
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) ซึ่งกันและกัน
Conformist — ยอมตาม model ของ upstream
หัวข้อที่มีชื่อว่า “Conformist — ยอมตาม model ของ upstream”ถ้า upstream ไม่ยอมร่วมมือ ฝั่ง downstream ก็จำต้อง “ยอมตาม” model ของ upstream ตอนเชื่อมต่อ — นี่คือ ConformistConformistทีมปลายน้ำยอม “ตามใจ” model ของทีมต้นน้ำทั้งหมดเพื่อตัดความซับซ้อนในการแปลภาษา ใช้เมื่อทีมต้นน้ำไม่มีแรงจูงใจจะรองรับเราStrategic Design ที่พบบ่อยที่สุดคือการเชื่อมกับ supplier ภายนอก เช่น payment provider ซึ่งแทบจะไม่มีทางเปลี่ยน API ให้คุณ เว้นแต่คุณจะเป็นลูกค้ารายใหญ่ ถ้าคุณเป็น downstream ที่ตั้ง Customer/Supplier ไม่ได้ และการทำ ACL ก็แพงเกินไป การยอมตาม model ของ provider จะทำให้ integration ง่ายขึ้น
ข้อเสียชัดๆ คือทีม downstream อาจต้อง เสียความชัดเจนของ domain model ตัวเอง เพราะต้องจัดให้ตรงกับ model ของ upstream แม้แนวคิดจะต่างจากมุมมองของเราก็ตาม ทางเลือกที่ดีกว่าถ้าพอจ่ายไหวคือใช้ Anticorruption LayerAnticorruption Layer (ACL)ชั้นกั้นที่ทีมปลายน้ำสร้างขึ้นเพื่อแปลง model ของระบบอื่นให้เป็นภาษาของ model ตัวเอง ป้องกันไม่ให้ model ภายนอกมา “ปนเปื้อน” model เราStrategic Design มากั้น เพื่อให้การเปลี่ยนแปลงที่จุดสัมผัสไม่ลามเข้า model ภายใน
สื่อสาร Context Map อย่างไรให้เข้าใจตรงกัน
หัวข้อที่มีชื่อว่า “สื่อสาร Context Map อย่างไรให้เข้าใจตรงกัน”เวลาวาด Context Map เราเขียน ประเภทความสัมพันธ์เชิงองค์กร และ ประเภทการเชื่อมต่อเชิงเทคนิค ลงบนเส้นที่เชื่อมสองบริบท พร้อมระบุว่าฝั่งไหน upstream ฝั่งไหน downstream ด้วยตัวอักษรหรือสัญลักษณ์

ลองอ่านแผนที่นี้เป็นไดอะแกรมสรุปความสัมพันธ์:
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;
ทำไม Context Map จึงสำคัญเชิงกลยุทธ์
หัวข้อที่มีชื่อว่า “ทำไม Context Map จึงสำคัญเชิงกลยุทธ์”ในหลายแง่ การสื่อสารระหว่างบริบท (ทั้งเทคนิคและองค์กร) สำคัญต่อทีมที่กำลังเริ่ม 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 คุณก็รู้ว่าหน้าที่ของคุณคือนำการตัดสินใจและมักต้องเป็นฝ่ายเริ่มสื่อสาร
จำ 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:
- Context Mapping — สรุปแนวคิด Context Map และรูปแบบความสัมพันธ์ระหว่างบริบทแบบกระชับ ต่อยอดจากเนื้อหาบทนี้ได้ทันที
- Bounded Context — ทบทวนว่า Bounded Context คืออะไร ก่อนจะเข้าใจว่าทำไมต้องมีแผนที่เชื่อมระหว่างมัน
- Anticorruption Layer — อธิบายชั้นแปลภาษาที่กัน model ปนเปื้อน ตรงกับหัวข้อ ACL ในบทนี้
- Shared Kernel — ขยายความรูปแบบการแบ่ง model ร่วมกันระหว่างสองบริบทที่ทับซ้อนกัน
- Strategic Design — มุมมองภาพใหญ่ว่า Context Mapping เป็นเครื่องมือเชิงกลยุทธ์ระดับองค์กรอย่างไร
เช็กความเข้าใจ — บทที่ 7
ข้อ 1 / 4Context Map ที่ดีควรแสดงอะไร?