Ubiquitous Language – ภาษาที่โค้ดกับธุรกิจพูดตรงกัน

ตอนที่ 3 ของซีรีส์ Domain-Driven Design ฉบับระบบธุรกิจจริง

Theme หลัก: ระบบบริหารพนักงาน (Staff / Employee Management System)

ในตอนที่ 2 เราเห็นแล้วว่า Domain Thinking คือการให้ domain เป็นผู้ตัดสินกฎของธุรกิจ

แต่ถึง domain จะอยู่ถูกที่แล้ว ระบบก็ยังพังได้ ถ้าเราใช้ “ภาษา” ผิด

DDD เรียกภาษานี้ว่า Ubiquitous Language


ปัญหาที่แท้จริง: เราคุยกันคนละภาษา

ลองนึกถึงบทสนทนาแบบนี้ในระบบพนักงาน:

  • ฝ่าย HR: “พนักงานยื่น คำขอเปลี่ยนกะ ได้วันละ 1 ครั้ง”
  • Developer: “โอเค เดี๋ยวเช็ค field request_count”
  • Code: canEdit = status != 2 && role != 3

ทุกคนคิดว่าตัวเองเข้าใจตรงกัน แต่จริง ๆ แล้ว:

  • ธุรกิจพูดถึง คำขอ (Request)
  • โค้ดพูดถึง ตัวเลขและสถานะลอย ๆ

ผลลัพธ์คือ ระบบที่:

ไม่มีใครมั่นใจว่าโค้ดสะท้อนกฎจริงครบหรือยัง


Ubiquitous Language คืออะไร

Ubiquitous Language (Ubiquitous อ่านว่า ยูบิค ควิเทิส) คือ:

ภาษาชุดเดียว ที่ถูกใช้ ร่วมกัน ระหว่าง

  • คนธุรกิจ
  • เอกสาร
  • โค้ด
  • การทดสอบ

ถ้าธุรกิจเรียกว่า “คำขอเปลี่ยนกะ”

โค้ดก็ต้องเรียกว่า:

  • ShiftChangeRequest
  • ไม่ใช่ RequestModel
  • ไม่ใช่ Transaction

ชื่อในโค้ด ไม่ควรแปล หรือย่อความหมายของธุรกิจ


ตัวอย่างชื่อที่ทำให้ Domain พัง

ในระบบพนักงาน มักเจอชื่อแบบนี้:

  • status = 1, 2, 3
  • type = ‘A’
  • flag = true
  • role = 99

โค้ดอาจทำงานได้ แต่คำถามคือ:

  • status = 2 แปลว่าอะไร?
  • ใครเป็นคนตัดสิน?
  • กฎนี้มาจากไหน?

ถ้าต้องเปิดเอกสารหรือถามคนอื่นทุกครั้ง แปลว่า ภาษาไม่ ubiquitous


เปลี่ยนตัวเลขให้เป็นภาษาธุรกิจ

แทนที่จะเขียนแบบนี้:

if (request.status != 1) return;

ให้เขียนแบบนี้:

enum ShiftRequestStatus {
  pending,
  approved,
  rejected,
  cancelled,
}

if (request.status != ShiftRequestStatus.pending) return;

ตอนนี้โค้ด:

  • อ่านแล้วรู้ความหมายทันที
  • ตรงกับภาษาที่ HR ใช้
  • ลดการตีความผิด

Ubiquitous Language ต้องอยู่ทุกที่

ภาษานี้ไม่ควรอยู่แค่ใน code

แต่ควรอยู่ใน:

  • ชื่อ class / method
  • test case
  • commit message
  • document

ตัวอย่าง test:

test('manager can approve pending shift request', () {
  // ...
});

ถ้าอ่าน test แล้ว HR เข้าใจได้ แปลว่าคุณมาถูกทางแล้ว


ระวังคำที่ดู technical เกินไป

คำบางคำดูเหมือนจะโอเค แต่จริง ๆ แล้วอันตราย:

  • process
  • handle
  • manage
  • data

เช่น:

  • processRequest() → ทำอะไร?
  • handleStaff() → handle ยังไง?

ให้ถามตัวเองว่า:

ธุรกิจใช้คำนี้จริงไหม?

ถ้าไม่ ให้เปลี่ยน


สร้างภาษาไปพร้อมกับธุรกิจ

Ubiquitous Language ไม่ใช่สิ่งที่คิดครั้งเดียวแล้วจบ

มันต้อง:

  • evolve ตามความเข้าใจ
  • ถูกแก้เมื่อพบว่าคำเดิมไม่ชัด
  • กล้าลบชื่อเก่า แม้จะเขียนไปแล้ว

การ refactor ชื่อ:

ไม่ใช่งาน cosmetic แต่เป็นงานออกแบบ domain


สรุปตอนที่ 3

  • ภาษา คือโครงสร้างของความคิด
  • ชื่อที่ไม่ชัด = domain ที่พัง
  • โค้ดควรอ่านเหมือนประโยคธุรกิจ

ถ้าคุณอธิบายระบบโดยเปิดโค้ดให้ฝ่ายธุรกิจดูไม่ได้

นั่นแปลว่าภาษาของระบบยังไม่ ubiquitous


ตอนต่อไป

ตอนที่ 4: Entity vs Value Object – สิ่งไหนควรมีตัวตนในระบบพนักงาน

เราจะเริ่มแตก domain model ของระบบพนักงานอย่างจริงจัง ว่าอะไรคือ entity อะไรคือ value object