Ubiquitous Language
Ubiquitous LanguageUbiquitous Languageภาษากลางที่ทุกคนในทีม (ทั้งนักพัฒนาและผู้เชี่ยวชาญธุรกิจ) ใช้ร่วมกัน อิงกับ domain model โดยตรง คำเดียวกันต้องหมายถึงสิ่งเดียวกัน และสะท้อนลงในโค้ดStrategic Design คือภาษากลางที่ “เข้มงวด” ซึ่งทุกคนในทีมใช้ร่วมกัน อิงกับ Domain ModelDomain ModelModel ของ Domain ที่ฝังกฎและกระบวนการทางธุรกิจไว้ในโค้ดจริง หัวใจของ DDD คือการพัฒนา domain model ที่ “เข้าใจธุรกิจอย่างลึกซึ้ง”Strategic Design โดยตรง เหตุที่ต้องเข้มงวดเพราะ “ซอฟต์แวร์รับมือความกำกวมได้ไม่ดี” (Fowler)
ปัญหาคลาสสิกคือ ผู้เชี่ยวชาญธุรกิจพูดภาษาหนึ่ง นักพัฒนาพูดอีกภาษาหนึ่ง แล้วต้อง “แปล” ไปมา ทุกการแปลคือโอกาสที่ความเข้าใจจะคลาดเคลื่อน DDD แก้ด้วยการสร้างภาษาเดียวที่ใช้ทั้งในการคุยและในโค้ด — ชื่อคลาส เมธอด ตัวแปร ควรสะท้อนคำในภาษานี้
คำเดียวกัน อาจหมายถึงคนละสิ่ง (polyseme)
หัวข้อที่มีชื่อว่า “คำเดียวกัน อาจหมายถึงคนละสิ่ง (polyseme)”Fowler ยกตัวอย่างบริษัทไฟฟ้าที่คำว่า “meter” (มิเตอร์) มีความหมายต่างกันเล็กน้อยในแต่ละแผนก ในการสนทนาเราอาจ “กลบ” ความต่างนี้ได้ แต่ในโลกที่แม่นยำของคอมพิวเตอร์ทำไม่ได้ ทางออกไม่ใช่บังคับให้ทุกคนใช้นิยามเดียว แต่คือการยอมรับว่าความหมายขึ้นกับ “บริบท” — ซึ่งนำเราไปสู่ Bounded ContextBounded Contextขอบเขตที่ชัดเจน (มักเป็นระบบย่อยหรือทีมหนึ่ง) ที่ model หนึ่งใช้ได้และมีความหมายแน่นอน ภายในขอบเขตนี้ Ubiquitous Language สอดคล้องกัน 100%Strategic Design ในบทถัดไป
Evans ย้ำว่า การเปลี่ยนภาษาคือการเปลี่ยน model เมื่อทีมพบคำที่อึดอัดหรือสื่อความไม่ตรง ผู้เชี่ยวชาญธุรกิจควร “คัดค้าน” และนักพัฒนาควรจับสัญญาณความกำกวม การปรับภาษาให้คมขึ้นคือการปรับ model ให้ดีขึ้น
เทียบกับ Cargo Shipping
หัวข้อที่มีชื่อว่า “เทียบกับ Cargo Shipping”ในระบบขนส่ง คำว่า “เส้นทาง” อาจหมายถึงสองสิ่งที่ต่างกันมาก: สิ่งที่ลูกค้าต้องการ (ต้นทาง–ปลายทาง–กำหนดเวลา) กับ แผนจริงที่จะเดินทาง (ผ่านท่าไหน เรือลำใด) ถ้าใช้คำเดียวปนกันจะสับสนทันที
DDD จึงตั้งชื่อแยกชัดเจน: Route SpecificationRoute SpecificationValue Object ที่ระบุ “ความต้องการของลูกค้า”: ต้นทาง ปลายทาง และกำหนดเวลาถึง — มีเมธอด isSatisfiedBy() ตรวจว่าแผนเดินทางตรงตามนี้หรือไม่Tactical Design = ความต้องการของลูกค้า, ItineraryItineraryValue Object ที่เป็น “แผนการเดินทางจริง” ของ Cargo ประกอบด้วยลำดับของ Leg (ช่วงการขนส่งแต่ละช่วง)Tactical Design = แผนเดินทางจริง คำเหล่านี้กลายเป็นทั้งศัพท์ที่ทีมพูดและชื่อคลาสในโค้ด
// ภาษาในโค้ดสะท้อนภาษาที่ทีมพูด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; }}