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

โฟกัส​ที่ Core Domain

ไม่ใช่​ทุก​ส่วน​ของ​ปัญหา​จะ “สำคัญ​เท่า​กัน” บาง​ส่วน​ของ application มี​ค่า​มากกว่า​ส่วน​อื่น และ​ต้องการ​ความ​ใส่ใจ​รวม​ถึง​การ​ลงทุน​มากกว่า​เพื่อ​ทำให้​ระบบ​ประสบ​ความ​สำเร็จ ระหว่าง​ที่​เรา​ทำ Knowledge CrunchingKnowledge Crunchingการ​บด​เคี้ยว​ความ​รู้ — ศิลปะ​การกลั่น​ข้อมูล​ที่​เกี่ยวข้อง​ออก​จาก problem domain ร่วม​กับ domain expert เพื่อ​สร้าง model ที่​มี​ประโยชน์​ต่อ business use caseProcess ร่วม​กับ domain expert หน้าที่​สำคัญ​คือ ลด​เสียง​รบกวน​ของ​สิ่ง​ที่​ไม่​สำคัญ เพื่อ​ให้​เรา​โฟกัส​กับ​สิ่ง​ที่สำคัญจริงๆ ได้

Model-Driven DesignDomain ModelModel ของ Domain ที่​ฝัง​กฎ​และ​กระบวนการ​ทาง​ธุรกิจ​ไว้​ใน code จริง หัวใจ​ของ DDD คือ​การ​พัฒนา domain model ที่ “เข้าใจ​ธุรกิจ​อย่าง​ลึกซึ้ง”Strategic Design เป็น​งาน​ที่​ยาก​และ​แพง จึง​ควร​สงวน​ไว้​สำหรับ​พื้นที่​ที่ “เป็น​หรือ​ตาย” ต่อ​ความ​สำเร็จ​ของ​ระบบ​เท่านั้น บท​นี้​จะ​สอน​วิธี เปิดเผย​พื้นที่​ที่​สำคัญ​ที่สุด ของ​ระบบ​ผ่าน​การ กลั่น (distillation)Distillationการกลั่น — กระบวนการ​แยก​ย่อย problem domain ก้อน​ใหญ่​ออก​เป็น subdomain เพื่อ​เผย​ว่า​ส่วน​ไหน​คือ core, supporting, generic ช่วย​ลด​ความ​ซับซ้อน​ใน problem space และ​บอกว่า​ควร​ลงแรง​ตรง​ไหนStrategic Design เพื่อ​ให้​รู้​ว่า​ควร​ลงแรง​ตรง​ไหน — แล้ว​ทุ่ม model ที่​ลึกซึ้ง​ที่สุด​ลง​ไป​กับ​สิ่ง​ที่​เป็น Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design


ระบบ​ขนาด​ใหญ่​ที่​สร้าง​เพื่อ problem domain ที่​ซับซ้อน ย่อม​ประกอบ​ด้วย component และ​ระบบ​ย่อย​หลาย​ชิ้น ทุก​ชิ้น​จำเป็นต่อ​การ​ทำงาน​ของ​ระบบ​โดย​รวม — แต่​ไม่ใช่​ทุก​ชิ้น​จะ​มี​ค่า​เท่า​กัน

เรา​ไม่​สามารถ (และ​ไม่​จำเป็น​ต้อง) กระจาย​แรง​และ​คุณภาพ​ให้​เท่าๆ กัน​ทั่ว​ทั้ง​ระบบ การ​พยายาม​ทำให้​ทุก​อย่าง​เท่าเทียม​กลับ​ทำให้ เสีย​โฟกัส จาก​พื้นที่​ที่​ต้อง​ทำให้​ถูกจริงๆ ทางออก​คือ​กลั่น problem domain ออก​มา​เพื่อ​เผย​ให้​เห็น​ว่า​อะไร​คือ​แก่น เมื่อ​แยก​ปัญหา​ก้อน​ใหญ่​ออก​เป็น​ชิ้น​เล็ก​ลง เรา​ก็​จัดสรร​ทรัพยากร​ได้​ดี​ขึ้น — ส่ง developer เก่ง​ที่สุด​ไป​อยู่​ใน​พื้นที่​ที่​สำคัญ​ที่สุด​ต่อ​ธุรกิจ ไม่ใช่​พื้นที่​ที่​แค่ “ท้าทาย​ทาง​เทคนิค” หรือ​ได้​เล่น framework ใหม่

1 model ครอบจักรวาล?

ฟัง​ดู​สม​เหตุ​สม​ผล​ที่​จะ​ใช้ model เดียว​อธิบาย​ทั้ง problem domain แต่ model นั้น​จะ​ต้อง​ตอบ​ทุก​ความ​ต้องการ จน​สุดท้าย​มัน​จะ ซับซ้อน​เกิน​ไป หรือ​ไม่​ก็ กว้าง​เสีย​จน​ไม่​สะท้อน​กระบวนการ​ธุรกิจ (business process) อะไร​ชัดเจน จำ​ไว้​ว่า DDD คือ​การ “ลด” ความ​ซับซ้อน — model ก้อน​เดียว​ขนาด​มหึมา มี​แต่​จะ​เพิ่ม​ความ​ซับซ้อน ทาง​ที่​ดี​กว่า​คือ​แตก problem space ออก​เป็น model เล็กๆ ที่​โฟกัส​และ​ผูก​กับ context ที่​ชัดเจน


จะ​รู้​ว่า​ควร​ลงแรง​ตรง​ไหน เรา​ต้อง​เข้าใจ​ก่อน​ว่า อะไร​ทำให้ app นี้​ควร​ค่า​แก่​การ​ออกแบบ​ตั้งแต่​แรก เรา​ต้อง​เข้าใจ​กลยุทธ์​ธุรกิจ และ​เข้าใจ​ว่า​ทำไม​การ​มี​อยู่​ของ​ซอฟต์แวร์​นี้​จึง​ทำให้​กลยุทธ์​นั้น​เป็น​จริง​ได้ คำถาม​ที่​ควร​ถาม​คือ:

  • ทำไม​เรา​ถึง​เขียน​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ​ของ​สำเร็จรูป (off-the-shelf)?
  • ระบบ​นี้​จะ​สร้าง​ความ​แตก​ต่าง​ให้​ธุรกิจ​อย่างไร และ​เข้า​กับ​กลยุทธ์​บริษัท​ตรง​ไหน?
  • ทำไม​ต้อง​ทำ​ใน​บ้าน (in-house) แทน​การ outsource?
  • ส่วน​ไหน​ของ​ซอฟต์แวร์​ที่​ให้ ความ​ได้​เปรียบ​ใน​การ​แข่งขัน กับ​ธุรกิจ?

ระวัง​เมื่อ business user ขอ “เพิ่ม feature” ให้​ระบบ​เดิม เพราะ​บ่อย​ครั้ง​สิ่ง​ที่​เขา​ขอ​ตั้ง​อยู่​บน ข้อ​จำกัด​ของ​ระบบ​ปัจจุบัน ไม่ใช่​สิ่ง​ที่​เขา​ต้อง​การจริงๆ ลอง​ถาม​ตัวเอง​ว่า​เรา​เข้าใจ “ทำไม” ที่​อยู่​เบื้องหลัง “อะไร” บ่อย​แค่​ไหน เมื่อ​เรา​เข้าใจความ​ต้องการ​ที่แท้​จริง เรา​มัก​เสนอ​ทาง​แก้​ที่​ดี​กว่า​ได้ — และ​ลูกค้า​มัก​ประหลาด​ใจ ตาม​ด้วย​ประโยค​คลาสสิก: “ระบบ​ทำ​แบบ​นั้น​ได้​ด้วย​หรือ?”

คุณ​คือ “ผู้​ทำให้​เป็น​ไป​ได้” (the enabler) ไม่ใช่​คน​ที่​เดิน​ตาม requirement ของ user อย่าง​ไร้​การ​ไตร่ตรอง

🛒 มอง​ทะลุ requirement ใน e-commerce

ลูกค้า​ธุรกิจ​อาจ​ขอ​ว่า “เพิ่ม​ช่อง​ค้นหา​สินค้า​ให้​ตรง​กับ​ฐาน​ข้อมูล​เดิม” แต่​สิ่ง​ที่​เขา​ต้อง​การจริงๆ คือ “อยาก​ให้​ลูกค้า​ค้น​เจอ​สินค้า​ที่​อยาก​ซื้อ​ได้​เร็ว​ขึ้น​เพื่อ​เพิ่ม​ยอด​ขาย” เมื่อ​เข้าใจ “ทำไม” เรา​อาจ​เสนอ recommendation engine หรือ​การ​จัด ranking — ซึ่ง​อาจ​เป็น Core Domain ที่แท้​จริง แทนที่​จะ​เป็น​แค่ search box ธรรมดา

ก่อน​เริ่ม​งานใดๆ ให้​ขอ “ภาพ​รวม project” เสมอ ใน​องค์กร​ใหญ่ กระบวนการ​ริเริ่ม project มัก​เกิด​ก่อน​ทีม dev จะ​เข้า​มา​เกี่ยวข้อง​เสีย​อีก มัก​จะ​มี เอกสารสั้นๆ ที่​อธิบาย​ว่า​ทำไม​บริษัท​ถึง​เลือก​สร้าง​ซอฟต์แวร์​ตัว​นี้​แทน​ตัว​อื่น — เอกสาร​นี้​มัก​ซ่อน “กุญแจ​สู่ core domain” เอา​ไว้

Domain Vision StatementDomain Vision Statementคำแถลง​วิสัยทัศน์​ของ domain — ข้อความ​สั้น ๆ ที่​จับใจความ​ว่า​อะไร​คือ​หัวใจ​ของ​ความ​สำเร็จ​ของ​ซอฟต์แวร์ เป้าหมาย​ธุรกิจ​คือ​อะไร และ​คุณค่า​อยู่​ตรง​ไหน ใช้​สร้าง​ความ​เข้าใจ​ร่วม​กัน​ใน​ทีม​ว่า​อะไร​คือ coreStrategic Design คือ​คำ​แถลงสั้นๆ ที่​จับใจความ​ว่า อะไร​คือ​หัวใจ​ของ​ความ​สำเร็จ เป้าหมาย​ธุรกิจ​คือ​อะไร และ​คุณค่า​อยู่​ตรง​ไหน เขียน​มัน​ออก​มา​ให้​ชัด share กับ​ทีม กระทั่ง​แปะ​ไว้​บน​ผนัง​ออฟฟิศ เพื่อ​เตือน​ทุก​คน​ว่า​เรา​กำลัง​เขียน​ซอฟต์แวร์​นี้​ไป​เพื่อ​อะไร

วิธี​ของ Amazon: Working Backwards

Amazon มี​วิธี​สร้าง domain vision ที่​เรียก​ว่า working backwards — สำหรับ feature ใหม่ product manager จะ​เขียน “ข่าว​ประชาสัมพันธ์​ภายใน” (internal press release) ประกาศ​ผลิตภัณฑ์​ที่​เสร็จ​แล้ว พร้อม​ระบุ​ประโยชน์​ที่​ลูกค้า​จะ​ได้ ถ้า​ลูกค้า​เป้าหมาย​ไม่รู้สึก​ว่า​มัน​น่า​ตื่นเต้น​หรือ​คุ้ม​ค่า PM ก็จะ refactor press release นั้น​จนกว่า feature จะ​ให้​คุณค่า​จริง — โฟกัส​ที่​ลูกค้า​ตั้งแต่​ก่อน​เริ่ม​เขียน code


problem domain ก้อน​ใหญ่​ถูก​แบ่ง​ออก​เป็น SubdomainSubdomainส่วน​ย่อย​ของ Domain ใหญ่ เช่น Domain e-commerce แตก​เป็น subdomain การ​สั่ง​ซื้อ การ​ชำระ​เงิน คลัง​สินค้า ฯลฯ อยู่​ใน “พื้นที่​ปัญหา” (problem space)Strategic Design เพื่อ​จัดการ​ความ​ซับซ้อน​และ​แยก​ส่วน​สำคัญ​ออก​จาก​ส่วน​ที่​เหลือ Millett เปรียบเทียบ​ไว้​สวยงาม: เหมือน​การ​ชำแหละ​หมู​ใน​ร้าน​ขาย​เนื้อ — หมู​ทั้ง​ตัว​ถูก​แบ่ง​ออก​เป็น “ชิ้น​ส่วน” ต่างๆ (สัน​ใน สัน​นอก สะโพก ขา​หมู) เช่น​เดียว​กับ​การ​แบ่ง problem space

รูปที่ 3-1: ชิ้นส่วนของหมู — เปรียบการแบ่ง problem domain ก้อนใหญ่ออกเป็น subdomain เหมือนการชำแหละหมูออกเป็นชิ้นส่วนต่างๆ แต่ละชิ้นมีคุณค่าและการใช้งานต่างกัน

subdomain คือ ‘พื้นที่​ความ​สามารถ’ ไม่ใช่​โครงสร้าง​องค์กร

subdomain เป็น แนวคิด​เชิง​นามธรรม อย่า​สับสน​กับ​ผัง​โครงสร้าง​องค์กร (แผนก/ทีม) ของ​บริษัท subdomain แทน พื้นที่​ของ​ความ​สามารถ (areas of capability) ที่​นิยาม​กระบวนการ​ธุรกิจ (business process) และ​ความ​สามารถ​เชิง function ของ​ระบบ

อย่า​เอา​เรื่อง​เทคนิค​เข้า​มา​ปน​ตอน​วิเคราะห์ problem space — Security, audit trail, logging ล้วน​เป็น เรื่อง infrastructure (เว้น​แต่ problem space ของ​คุณ​คือ security เอง) ให้​โฟกัส​ที่ domain เป็น​อันดับ​แรก

เมื่อ​กลั่น problem domain เรา​จะ “แบ่ง​แล้ว​พิชิต” (divide and conquer) ความ​ซับซ้อน​ได้ subdomain หลาย​ตัว​จะ generic กับ​ธุรกิจ​องค์กร​ทั่วไป (เช่น ระบบ​รายงาน การ​แจ้ง​เตือน) เรา​เรียก​ว่า generic domainGeneric Subdomainปัญหา​ที่​แก้​กัน​มา​แล้ว​ทั่วไป เช่น ระบบ login บัญชี การ​แจ้ง​เตือน — ควร​ใช้​ของ​สำเร็จรูป​หรือ library แทน​การ​เขียน​เองStrategic Design ส่วน​พื้นที่​ที่​ทำให้​สินค้า​ของ​บริษัท​คุณ แตก​ต่าง​จาก​คู่แข่ง และ​สร้าง​ความ​ได้​เปรียบ คือ Core DomainCore Domainsubdomain ที่​สำคัญ​และ​สร้าง​ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​มาก​ที่สุด เป็น​เหตุผล​ที่​เรา​ต้อง​สร้าง​ซอฟต์แวร์​เอง​แทน​การ​ซื้อ ควร​ทุ่ม​ทีม​เก่ง​ที่สุด​ลง​ตรง​นี้Strategic Design — เหตุผล​ที่​คุณ​ต้อง​เขียน​ซอฟต์แวร์​นี้​เอง ที่​เหลือ​คือ supporting domainSupporting Subdomainส่วน​ที่​จำเป็น​และ​เฉพาะ​กับ​ธุรกิจ​เรา แต่​ไม่ใช่​จุด​ที่​สร้าง​ความ​ได้​เปรียบ ไม่มี​ของ​สำเร็จรูป​ที่​พอดี จึง​ต้อง​ทำ​เอง แต่​ลงทุน​น้อย​กว่า coreStrategic Design ซึ่ง​เป็น​ตัว​สนับสนุน core


ลอง​ดู domain ของ​เว็บ​ประมูล​ออนไลน์ มัน​คือ problem domain ก้อน​ใหญ่​ก้อน​หนึ่ง​ที่​ยัง​ไม่​ถูก​แยก​ย่อย

รูปที่ 3-2: domain ของเว็บประมูลออนไลน์ — ยังเป็น problem domain ก้อนเดียวขนาดใหญ่ที่ยังไม่ถูกกลั่นออกเป็น subdomain

หลัง​การ knowledge crunching เรา​แบ่ง​มัน​ออก​เป็น subdomain ได้​ดังนี้: Membership (สมัคร​สมาชิก ความ​ชอบ ข้อมูล​สมาชิก), Seller (กิจกรรม​ของ​ผู้​ขาย), Auction (จัดการ​เวลา​ประมูล​และ​การ​ประมูล​แข่ง​ราคา), Listing (catalog สินค้า​ที่​เปิด​ประมูล) และ Dispute Resolution (จัดการ​ข้อ​พิพาท​ระหว่าง​สมาชิก​กับ​ผู้​ขาย)

รูปที่ 3-3: domain ของเว็บประมูลถูกกลั่นออกเป็น subdomain ได้แก่ Membership, Seller, Auction, Listing และ Dispute Resolution

ขั้น​ต่อ​ไป​คือ​จัด​ประเภท subdomain เป็น core / supporting / generic ตาม​คุณค่า​ที่​มี​ต่อ​ธุรกิจ

รูปที่ 3-4: subdomain ของเว็บประมูลถูกจัดประเภท — Seller และ Auction เป็น Core Domain, Membership และ Listing เป็น Supporting, Dispute Resolution เป็น Generic

  • Seller และ Auction = Core Domain — Seller มี​ตรรกะ​การ​คิด​เรตติ้ง​และ​ค่า​ธรรมเนียม​ผู้​ขาย ส่วน Auction คือ​กลไก​การ​ประมูล​และ​จัดการ​การ​แข่ง​ราคา ทั้ง​คู่​คือ​หัวใจ​ของ​ความ​สำเร็จ
  • Membership และ Listing = Supporting — ช่วย​ให้​ผู้​ประมูล​สร้าง​บัญชี​และ​หา​สินค้า​เจอ แต่​ไม่​ได้​นิยาม​ว่า​ธุรกิจ​นี้​คือ​อะไร
  • Dispute Resolution = Generic — เป็น​แค่​ระบบ ticket จัดการ​เคส​ข้อ​พิพาท หา​ซื้อ off-the-shelf มา​ใช้ได้

จะ​รู้​ว่า​อะไร​คือ core ลอง​ถาม​ตัวเอง​ว่า: ส่วน​ไหน​ของ​ผลิตภัณฑ์​ที่​จะ​ทำให้​มัน​สำเร็จ? ทำไม​ส่วน​เหล่า​นั้น​ถึง​สำคัญ? และ​ทำไม​ถึง ซื้อ​สำเร็จรูป​มา​ใช้​ไม่​ได้? พูด​อีก​อย่าง​คือ — อะไร​ทำให้​ระบบ​นี้ “ควร​ค่า​แก่​การ​สร้าง”

Core Domain แทน ความ​ได้​เปรียบ​ใน​การ​แข่งขัน​พื้นฐาน ที่​บริษัท​จะ​ได้​จาก​การ​ส่ง​มอบ​ซอฟต์แวร์​นี้ และ​มัน​ไม่​ได้​ชัดเจน​เสมอ​ไป ถ้า generic domain ควร “ซื้อ​เข้า​มา​และ​พัฒนา​ให้​น้อย​ที่สุด” core domain ก็​คือ​ขั้ว​ตรง​ข้าม — มัน​ต้องการ developer ที่​เก่ง​ที่สุด​ของ​คุณ (Millett เรียก​พวก​เขา​ว่า “คอมมานโด”) Core Domain อาจ​ไม่ใช่​ส่วน​ที่​ใหญ่​ที่สุด​ใน​แง่​ปริมาณ​เทคโนโลยี แต่​ต้องการ​การ​ลงทุน​มาก​ที่สุด

Core Domain ที่ ‘มอง​ไม่​เห็น’ ของ Pottermore.com

Pottermore.com เป็น​ที่​เดียว​บน​เว็บ​ที่​ขาย​หนังสือ Harry Potter แบบ​ดิจิทัล หน้าตา​ก็​เหมือน​เว็บ e-commerce ทั่วไป — เลือก​สินค้า ใส่​ตะกร้า จ่าย​เงิน แต่ core domain คือ​สิ่ง​ที่​ลูกค้า​มอง​ไม่​เห็น: หนังสือ​ไม่​ได้​ล็อก​ด้วย DRM แต่​ฝัง ลายน้ำ​ที่​มอง​ไม่​เห็น (invisible watermark) ไว้ เพื่อ​ให้​ติดตาม​ได้​หาก​มี​คน​นำ​ไป​เผยแพร่​อย่าง​ผิด​กฎหมาย​บน​เว็บ เทคโนโลยี​ลายน้ำ​นี่แหละ​คือ​สิ่ง​ที่​ทำให้​ธุรกิจ​ต่าง​จาก​คน​ขาย e-book ราย​อื่น และ​เป็น​เหตุผล​ที่​ต้อง​สร้าง​เอง​แทน​การ​ไป​ขาย​ผ่าน iTunes

Core Domain เปลี่ยน​ไป​ตาม​กาล​เวลา ถ้า​คุณ​สำเร็จ คู่แข่ง​ก็​จะ​เลียน​แบบ Core Domain จึง​ต้อง วิวัฒน์ (evolve) ต่อ​ไป​เพื่อ​ให้​ธุรกิจ​นำ​หน้า​อยู่​เสมอ ทีม dev ต้อง​เข้าใจ​ข้อ​นี้ และ​ทำให้ code สอดคล้อง​กับ​คุณค่า​ที่​เปลี่ยน​ไป​ของ​ธุรกิจ

หนึ่ง​ใน​การ​เปลี่ยน mindset ที่​สำคัญ​ที่สุด​คือ มอง core domain เป็น product ไม่ใช่ project ที่​จบ​แล้ว​จบ​เลย ซอฟต์แวร์​สำหรับ business product แทบ​ไม่​เคย “เสร็จ” — มัน​จะ​มี​ชีวิต​ผ่าน​ช่วง​เวลา​ของ​การ​เพิ่ม feature เรื่อยๆ จนกว่า​มัน​จะ​ไม่​ให้​คุณค่า​อีก​ต่อ​ไป คุย​กับ business sponsor เรื่อง​อนาคต​ของ​ผลิตภัณฑ์ เพื่อ​โฟกัส​ความ​พยายาม​ใน​การ​เขียน code ให้​ถูก​จุด

กับดัก: เร่ง​ส่ง​ของ​จน​ยอม​ทิ้ง​คุณภาพ​ของ core

บ่อย​ครั้ง​ซอฟต์แวร์ core domain ไม่​ถูก​มอง​เป็น product ที่​ต้อง​ดูแล แต่​ถูก​บีบ​ให้ แลก​คุณภาพ​กับ​ความเร็ว​ใน​การ​ออก​สู่​ตลาด (time to market) โดย​เน้น​ที่​เดดไลน์​มากกว่า​การ​ลงทุน​ระยะ​ยาว ผล​คือ codebase ที่​ดูแล​ยาก​และ​กลาย​เป็น Big Ball of MudBig Ball of Mudระบบ​ที่​ปนเป​กัน​ยุ่งเหยิง​ไม่มี​ขอบเขต​ชัด ให้​ลาก​เส้น​ล้อม​ไว้​แล้ว​ยอมรับ​สภาพ ไม่​พยายาม​ทำ model ละเอียด​ใน​นั้น และ​ระวัง​ไม่​ให้​ลาม​ไป context อื่นStrategic Design (BBoM) ใน​ที่สุด

ทางออก​เมื่อ​เดดไลน์​ขยับ​ไม่​ได้​คือ ตัด​ขอบเขต feature (descope) เพื่อ​รักษา​คุณภาพ​ไว้ ไม่ใช่​ลด​คุณภาพ — แต่​จะ​ทำ​เช่น​นี้​ได้ คุณ​ต้อง​มี vision ร่วม​กัน​ทั้ง​ทีม เพื่อ​รู้​ว่า feature ไหน “สำคัญ​ที่สุด” จริงๆ


Generic domainGeneric Subdomainปัญหา​ที่​แก้​กัน​มา​แล้ว​ทั่วไป เช่น ระบบ login บัญชี การ​แจ้ง​เตือน — ควร​ใช้​ของ​สำเร็จรูป​หรือ library แทน​การ​เขียน​เองStrategic Design คือ subdomain ที่​ระบบ​ธุรกิจ​ขนาด​ใหญ่​ส่วน​มาก​มี​เห​มือ​นๆ กัน เช่น บริการ​ส่ง​อีเมล package บัญชี ชุด​รายงาน — ไม่ใช่ core แต่​ธุรกิจ​ก็​ขาด​มัน​ไม่​ได้ เพราะ​ไม่​ได้​ให้​ความ​ได้​เปรียบ จึง​ไม่​สม​เหตุ​สม​ผล​ที่​จะ​ทุ่ม​แรง​สร้าง​เอง ควร ซื้อ​เข้า​มา หรือ​มอบหมาย​ให้ junior developer ทำ เพื่อ​ปลดปล่อย​คน​เก่ง​ที่สุด​ไป​ทุ่ม​กับ​งาน core

‘core’ ของ​คน​หนึ่ง อาจ​เป็น ‘generic’ ของ​อีก​คน

อีเมล​คือ generic domain สำหรับ​เว็บ​ประมูล​ทั่วไป — แต่​สำหรับ Groupon หรือ Wowcher ที่​ธุรกิจ​ถูก​นิยาม​ด้วย​การ​ส่ง​อีเมล​โปรโมชัน​แบบ​จำกัด​เวลา ระบบ email/CRM ที่​ซับซ้อน​กลับ​เป็น core domain ของ​พวก​เขา จง​ตัดสิน​จาก​คุณค่า​ต่อ​ธุรกิจ “ของ​คุณ” เสมอ

Supporting domainSupporting Subdomainส่วน​ที่​จำเป็น​และ​เฉพาะ​กับ​ธุรกิจ​เรา แต่​ไม่ใช่​จุด​ที่​สร้าง​ความ​ได้​เปรียบ ไม่มี​ของ​สำเร็จรูป​ที่​พอดี จึง​ต้อง​ทำ​เอง แต่​ลงทุน​น้อย​กว่า coreStrategic Design คือ subdomain ที่​เหลือ ไม่​ได้​นิยาม​ว่า​ระบบ​ทำ​อะไร แต่​ช่วย “ค้ำ” core เช่น function เลือก​ดู catalog สินค้า​ของ Amazon — ไม่​ได้​นิยาม​ว่า Amazon เป็น​บริษัท​อะไร และ​ก็​ไม่​ต่าง​จาก​เว็บ e-commerce ราย​อื่น แต่​มัน​ช่วย​ติดตาม user journey ไป​ป้อน recommendation engine เช่น​เดียว​กับ generic domain ถ้า​ทำได้​ก็​ควร​ซื้อ​สำเร็จรูป หรือ​ไม่​เช่น​นั้น​ก็​ไม่​ควร​ลงทุน​หนัก — บาง​ครั้ง กระบวนการ​แบบ manual ก็​ตอบ​โจทย์​ได้ โดย​ไม่​ต้อง​เขียน code ด้วย​ซ้ำ


ภายใน​แต่ละ subdomain เรา​สร้าง model ขึ้น​มา​หนึ่ง​ตัว และ solution ก็ map ตาม subdomain เหล่า​นั้น ใน​เว็บ​ประมูล ระบบ​ถูก​แบ่ง​เป็น2 app จริง: core กับ supporting domain สร้าง​เป็น​เว็บ app ที่​เขียน​เอง (bespoke) ส่วน dispute domain ใช้ package สำเร็จรูป

รูปที่ 3-5: solution map ไปตาม subdomain ของเว็บประมูล — core/supporting สร้างเป็น bespoke web app (ทุ่ม developer เก่งที่สุดที่ core) ส่วน Dispute Resolution ใช้ package สำเร็จรูป


ไม่ใช่​ทุก​ส่วน​ของ​ระบบ​ที่​ต้อง​ออกแบบ​ให้​ดี

หัวข้อ​ที่​มีชื่อ​ว่า “ไม่ใช่​ทุก​ส่วน​ของ​ระบบ​ที่​ต้อง​ออกแบบ​ให้​ดี”

ภายใน​แต่ละ subdomain จะมี model ที่​แทน​ตรรกะ​และ​กฎ​ธุรกิจ​ของ​พื้นที่​นั้น — แต่ model ทุก​ตัว​ไม่​จำเป็น​ต้อง​มี​คุณภาพ​เท่า​กัน เมื่อ​เข้าใจ subdomain ต่างๆ แล้ว เรา​จัดสรร​แรง​ให้​เหมาะสม​ได้ และ​นำ model-driven design patterns ของ DDD ไป​ใช้​เฉพาะ​พื้นที่​ที่​ได้​ประโยชน์​มาก​ที่สุด

อย่า​เสีย​เวลา refactor code ทั้งหมด — แรง​โฟกัส​หลัก​ต้อง​อยู่​ที่ core domain ถ้า​ได้ code ที่ “ทำงาน​ได้​แต่​ไม่​เนี้ยบ” ใน​ส่วน supporting/generic ก็​ปล่อย​มัน​ไว้ Good is good enough (ดี​พอ​ก็​เพียงพอแล้ว) ความ​สมบูรณ์​แบบ​เป็น​ภาพลวงตา และ​ควร​สงวน​ไว้​สำหรับ​สิ่ง​ที่​เป็น core เท่านั้น

ปล่อย​ให้​มี BBoM ก้อน​เล็กๆ อยู่​ได้ ตราบ​ใด​ที่​มัน​ถูก​ล้อม​ด้วย​ขอบเขต​ที่​ชัดเจน ธุรกิจ​ไม่​ได้​สนใจ​คุณภาพ code ของ​พื้นที่​ที่​จำเป็น​แต่​ไม่ใช่​กุญแจ​ของ​ระบบ

โฟกัส​ที่​ขอบเขต​สะอาด มากกว่า model ที่​สมบูรณ์​แบบ

หัวข้อ​ที่​มีชื่อ​ว่า “โฟกัส​ที่​ขอบเขต​สะอาด มากกว่า model ที่​สมบูรณ์​แบบ”

ใน​ระบบ​ใหญ่​ที่​วิวัฒน์​มา​นาน ย่อม​มี​พื้นที่​ที่​ไม่​สมบูรณ์​แบบ ถ้า​มี​ส่วน​ที่​หน้าตา​เหมือน BBoM สิ่ง​ที่​ดี​ที่สุด​คือ ขีด​เส้น​ล้อม​มัน​ไว้ เพื่อ​กัน “โคลน” (mud) ไม่​ให้​ลาม​ไป​ยัง​พื้นที่​ใหม่ ใช้ Anticorruption LayerAnticorruption Layer (ACL)ชั้น​กั้น​ที่​ทีม​ปลาย​น้ำ​สร้าง​ขึ้น​เพื่อ​แปลง model ของ​ระบบ​อื่น​ให้​เป็น​ภาษา​ของ model ตัวเอง ป้องกัน​ไม่​ให้ model ภายนอก​มา “ปน​เปื้อน” model เราStrategic Design (ACL) ห่อ​การ​สื่อสาร​กับ code legacy หรือ code ของ​บุคคล​ที่​สาม เพื่อ​รักษา​ความ​ถูกต้อง​ของ Bounded ContextBounded Contextขอบเขต​ที่​ชัดเจน (มัก​เป็น​ระบบ​ย่อย​หรือ​ทีม​หนึ่ง) ที่ model หนึ่ง​ใช้ได้​และ​มี​ความหมาย​แน่นอน ภายใน​ขอบเขต​นี้ Ubiquitous Language สอดคล้อง​กัน 100%Strategic Design ใหม่​ไว้ ป้องกัน model หนึ่ง​ไม่​ให้​ปน​เปื้อน​อีก model (เรา​จะ​ลง​ลึก​เรื่อง ACL ในบท Context Mapping)

รูปที่ 3-6: การรับมือกับ legacy — ขีด Bounded Context ล้อม model ใหม่ ใช้ขอบเขตชัดเจนกั้น Legacy Ball of Mud ไว้ และสื่อสารผ่าน integration point ที่กำหนดไว้แน่นอน

🚢 โฟกัส core ใน​ระบบ​ขนส่ง​สินค้า

ใน​ระบบ Cargo Shipping ของ​เรา core domain คือ​การ​วางแผน​เส้นทาง​และ​การ​จอง​การ​ขนส่ง (Route SpecificationRoute SpecificationValue Object ที่​ระบุ “ความ​ต้องการ​ของ​ลูกค้า”: ต้นทาง ปลายทาง และ​กำหนด​เวลา​ถึง — มี method isSatisfiedBy() ตรวจ​ว่า​แผน​เดินทาง​ตรง​ตาม​นี้​หรือ​ไม่Tactical Design, ItineraryItineraryValue Object ที่​เป็น “แผนการ​เดินทาง​จริง” ของ Cargo ประกอบ​ด้วย​ลำดับ​ของ Leg (ช่วง​การ​ขนส่ง​แต่ละ​ช่วง)Tactical Design) — นี่​คือ​จุด​ที่​กฎ​ธุรกิจ​ซับซ้อน​และ​สร้าง​ความ​ได้​เปรียบ จึง​ควร​ทุ่ม model ที่​ลึก​ที่สุด​ลง​ไป

ส่วน​การ​ออก​ใบ​แจ้ง​หนี้ (billing), การ​ส่ง​อีเมล​ยืนยัน, หรือ​ระบบ login ของ​พนักงาน เป็น generic / supporting domain — ซื้อ​สำเร็จรูป​หรือ​มอบหมาย​ให้ junior ทำ และ​ล้อม​ระบบ tracking เก่า​ที่​เป็น legacy ไว้​ด้วย ACL เพื่อ​ไม่​ให้​มัน​ลาม​มา​บั่นทอน​คุณภาพ​ของ core

ใน​โลก​อุดมคติ คุณภาพ​ควร​มา​เป็น​อันดับ​หนึ่ง​เสมอ — แต่​ต้อง practical ด้วย บาง​ครั้ง core domain ของ​ระบบ​ใหม่​ต้อง​ชิง​ออก​ตลาด​ก่อน​ใคร หรือ​บาง​ครั้ง​ธุรกิจ​ยัง​ไม่​แน่ใจ​ว่า​ไอเดีย​จะ​สำเร็จ​และ​กลาย​เป็น core หรือ​ไม่ ใน​กรณี​นี้​ธุรกิจ​อยาก เรียนรู้​เร็ว​และ​ล้ม​เร็ว (fail fast) โดย​ไม่​ลงแรง up-front มาก version แรก​อาจ​ไม่​ประณีต — ซึ่ง​ก็​ยอมรับ​ได้ แต่ ถ้า​มัน​สำเร็จ​และ​คุ้ม​ที่​จะ​ลงทุน​ต่อ คุณ​ต้อง refactor เพื่อ​รองรับ​การ​วิวัฒน์ มิ​ฉะนั้น technical debt ที่​สะสม​จาก​การ​เร่ง​ส่ง​จะ​กลาย​เป็น​ปัญหา​ใน​ภายหลัง

เมื่อ​พัฒนา model ใน supporting subdomain ให้​สร้าง​มัน​แบบ​แยก​เดี่ยวๆ โดย​คิด​เรื่อง การ​แทนที่ ไว้​ใน​ใจ กั้น​มัน​จาก model อื่น code legacy และ​บริการ​ภายนอก​ด้วย​ขอบเขต​ที่​สะอาด การ​ออกแบบ​เพื่อ “แทนที่​ได้” (designed for replacement) แทน “ใช้​ซ้ำ” (reuse) ทำให้​ได้ supporting subdomain ที่​ดี​พอ​โดย​ไม่​ต้อง​เสียแรง​ทำให้​สมบูรณ์​แบบ — วัน​ข้าง​หน้า​จะ​เปลี่ยน​ไป​ใช้​ของ​สำเร็จรูป​หรือ​เขียน​ขึ้น​ใหม่​ก็​ทำได้​ง่าย


ธุรกิจ​สร้าง​ซอฟต์แวร์​เอง​ด้วย​หลาย​เหตุผล — ถ้า​ทำได้​ถูก​กว่า เร็ว​กว่า หรือ​ฉลาด​กว่า ก็​เป็น​ตัว​เลือก​ที่​ดี​ใน​การ​สร้าง​เอง แต่​ถ้า​พบ​ว่า​สิ่ง​ที่​กำลัง​สร้าง​เป็น generic ทั้งหมด หรือ​เป็น​แค่​ตัว support app อื่น​ใน​องค์กร — แปล​ว่า​คุณ ไม่มี core domain ใน​กรณี​นี้ อย่า​พยายาม​ยัด practices และ principles ทั้งหมด​ของ DDD ลงไป

คุณ​ยัง​ได้​ประโยชน์​จาก strategic patterns ของ DDD อยู่ แต่ tactical patterns ของ model-driven design อาจ​เป็นการ​เสียแรง​เปล่า (เรา​จะ​พูด​ถึง​เมื่อไร​ควร/ไม่​ควร​ใช้ tactical patterns ใน​บท​หลัง)

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

ใช้ Distillation แตก problem domain ก้อน​ใหญ่​ออก​เป็น Core / Supporting / Generic เพื่อ​ลด​ความ​ซับซ้อน​และ​รู้​ชัด​ว่า​ควร​ลงแรง​ตรง​ไหน — ทุ่ม developer เก่ง​ที่สุด​ไว้​ที่ Core Domain เพราะ​มัน​คือ​เหตุผล​ที่​คุณ​ต้อง​เขียน​ซอฟต์แวร์​นี้​ขึ้น​มา​เอง ส่วน supporting/generic ให้​ซื้อ outsource หรือ​มอบหมาย​ให้ junior ทำ และ​จำ​ไว้​เสมอ​ว่า ไม่ใช่​ทุก​ส่วน​ต้อง​ออกแบบ​ให้​ดี​เท่า​กัน — ความ​สมบูรณ์​แบบ​มี​ไว้​สงวน​ให้ core เท่านั้น ส่วน legacy ที่​รก​รุงรัง ให้​ล้อม​ด้วย​ขอบเขต​ที่​ชัดเจน​และ ACL


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

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

  • Domain (Subdomain vs Core Domain) — นิยาม​พื้นฐาน​ของ domain และ​การ​จัด​ประเภท core/supporting/generic ที่​บท​นี้​ใช้​ตลอด
  • Subdomain — หลักการ​แบ่ง problem domain ก้อน​ใหญ่​ออก​เป็น​พื้นที่​ความ​สามารถ​ย่อยๆ ตาม​ที่​บท​นี้​อธิบาย​ด้วย​ตัวอย่าง​เว็บ​ประมูล
  • Strategic Design — ภาพ​รวม​ของ​การกลั่น (distillation) และ​วาง​กลยุทธ์​ระดับ domain ก่อน​ลงมือ​ทำ tactical patterns
  • Anti-Corruption Layer — เทคนิค​ขีด​ขอบเขต​กัน legacy Big Ball of Mud ไม่​ให้​ปน​เปื้อน model ใหม่ ที่​กล่าว​ถึง​ถึง​ใน​หัวข้อ “โฟกัส​ที่​ขอบเขต​สะอาด”

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

ข้อ 1 / 4

ทำไม DDD ถึงแนะนำให้กลั่น (distill) problem domain ก้อนใหญ่ออกเป็น subdomain?