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

Ubiquitous Language

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

ปัญหา​คลาสสิก​คือ ผู้เชี่ยวชาญ​ธุรกิจ​พูด​ภาษา​หนึ่ง นัก​พัฒนา​พูด​อีก​ภาษา​หนึ่ง แล้ว​ต้อง “แปล” ไปมา ทุก​การ​แปล​คือ​โอกาส​ที่​ความ​เข้าใจ​จะ​คลาดเคลื่อน DDD แก้​ด้วย​การ​สร้าง​ภาษา​เดียว​ที่​ใช้​ทั้ง​ใน​การ​คุย​และ​ใน code — ชื่อ class method ตัวแปร ควร​สะท้อน​คำ​ใน​ภาษา​นี้

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

ภาษา = model

Evans ย้ำ​ว่า การ​เปลี่ยน​ภาษา​คือ​การ​เปลี่ยน model เมื่อ​ทีม​พบ​คำ​ที่​อึดอัด​หรือ​สื่อ​ความ​ไม่​ตรง ผู้เชี่ยวชาญ​ธุรกิจ​ควร “คัดค้าน” และ​นัก​พัฒนา​ควร​จับ​สัญญาณ​ความ​กำกวม การ​ปรับ​ภาษา​ให้​คม​ขึ้น​คือ​การ​ปรับ model ให้​ดี​ขึ้น

🚢 หา​คำ​ที่ “คม”

ใน​ระบบ​ขนส่ง คำ​ว่า “เส้นทาง” อาจ​หมาย​ถึง​สอง​สิ่ง​ที่​ต่าง​กัน​มาก: สิ่ง​ที่​ลูกค้า​ต้องการ (ต้นทาง–ปลายทาง–กำหนด​เวลา) กับ แผน​จริง​ที่​จะ​เดินทาง (ผ่าน​ท่า​ไหน เรือ​ลำ​ใด) ถ้า​ใช้​คำ​เดียว​ปน​กัน​จะ​สับสน​ทันที

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

method isSatisfiedBy อ่าน​ออก​เป็น​ประโยค​ธุรกิจ​ได้​เลย — นั่น​คือ​สัญญาณ​ของ Ubiquitous Language ที่​ดี
// ภาษาใน code สะท้อนภาษาที่ทีมพูด
class RouteSpecification {
constructor(
readonly origin: UnLocode, // ต้นทาง
readonly destination: UnLocode, // ปลายทาง
readonly arrivalDeadline: Date, // กำหนดถึง
) {}
// “แผนนี้ตรงตามที่ลูกค้าต้องการไหม?” — อ่านได้เหมือนประโยคธุรกิจ
isSatisfiedBy(itinerary: Itinerary): boolean {
return itinerary.firstLeg().from.equals(this.origin)
&& itinerary.lastLeg().to.equals(this.destination)
&& itinerary.finalArrival() <= this.arrivalDeadline;
}
}

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

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

  • Ubiquitous Language — นิยาม​และ​หลักการ​ของ​ภาษา​กลาง​ที่​บท​นี้​อธิบาย​โดยตรง
  • Bounded Context — บริบท​ที่​ทำให้​คำ​แบบ “meter” หรือ “เส้นทาง” มี​ความหมาย​ต่าง​กัน​ได้​โดย​ไม่​ขัดแย้ง​กัน
  • Domain Model — model ที่ Ubiquitous Language ต้อง​สะท้อน​ตรง​กัน​ทั้ง​ใน​บทสนทนา​และ​ใน code
  • Specification — pattern เบื้องหลัง class RouteSpecification ใน​ตัวอย่าง ที่​ทำให้​กติกา​ทาง​ธุรกิจ​อ่าน​ออก​เป็น​ภาษาธุรกิจได้ตรงๆ

เช็กความเข้าใจ — Stage 1

ข้อ 1 / 3

ทำไม Ubiquitous Language จึงต้อง “เข้มงวด”?