แนะนำการพัฒนาซอฟแวร์แบบ Domain-Driven Design

Kunanon Chumsaeng
CSCMU Undergrad Seminar
3 min readApr 13, 2020

ในการพัฒนาซอฟแวร์แบบดั่งเดิม (Waterfall) ทำให้ทีมผู้พัฒนาออกแบบระบบออกมาไม่เหมาะกับตัวงานหรือทำให้เปลี่ยนแปลงภายหลังได้ยาก เนื่องจากในจุดเริ่มต้นไม่มีความเข้าใจ domain ของตัวงาน (ยกเว้นทำงานที่เกี่ยวข้องกับเรื่องนั้นมานานระดับหนึ่งแล้ว) เทคนิค Domain-Driven Design จะเข้ามาแก้ปัญหานี้ พร้อมทั้งจะเป็นตัวนำทางในการพัฒนาซอฟแวร์ตลอดทั้งระบบ แต่ก่อนอื่นเราต้องไปทำความรู้จัก Domain แลพ Model กันก่อน

อะไรคือ Domain และ Model?

แยก Domain กับ Model ด้วยตัวอย่างดังนี้

Photo by The New York Public Library on Unsplash
Photo by British Library on Unsplash

รูปแรกคือ โลกของเราทั้งใบ รูปที่สองคือ แผนที่ยุโรป กล่าวคือ โลกทั้งใบคือ Domain และ แผนที่ยุโรปคือ Model ยุโรปอยู่บนโลกแต่เราเห็นได้ไม่ชัดจากภาพถ่าย แผนที่เป็นตัวแสดงที่เจาะจงข้อมูลของยุโรปออกมา สรุปได้ดังนี้

Domain: กลุ่มก้อนของข้อมูลหรือกิจกรรมใดๆ
Model: ระบบของนามธรรม (Abstraction)ที่แสดงส่วนหนึ่งของ Domain
Model กลั่นกรองข้อมูลและข้อสันนิษฐานที่เกี่ยวกับ Domain

สมมุติว่าเราต้องเขียนซอฟแวร์สำหรับการจองเรือขนสินค้าเราจะปั่น Model ของเรือและสินค้าอย่างไร

เรือหนึ่งลำขนสินค้าได้หลายชิ้น

แต่ใน requipment บอกว่า สามารถ “overbooking” ได้ overbooking คือการที่จองเกินน้ำหนักที่เรือสามารถบรรทุกได้ ยกตัวอย่างโค้ดที่ overbooking ได้ 10% ดังนี้

public int makeBooking(Cargo cargo, Voyage voyage) {
double maxBooking = voyage.capacity() * 1.1;
if ((voyage.bookedCargoSize() + cargo.size()) > maxBooking)
return –1;
int confirmation = orderConfirmationSequence.next();
voyage.addCargo(cargo, confirmation);
return confirmation;

แต่ถ้าเราต้องเปลี่ยนกฏการ overbooking นี้ในอนาคต โค้ดข้างบนจะยุ่งเหยิงมากขึ้นแน่ๆ เราสามารถยก design pattern Strategy เข้ามาแก้ปัญหานี้ได้ โดยยกระดับ logic ของ overbooking ให้การเป็น abstraction อีกขั้นหนึ่ง

class OverbookingPolicy {
public boolean isAllowed(Cargo cargo, Voyage voyage) {
return (cargo.size() + voyage.bookedCargoSize()) <=
(voyage.capacity() * 1.1);
}
}

แต่กว่าเราจะรู้ได้ว่าการขนสินค้าด้วยเรือมีกฏแบบนี้ หรือความไม่แน่นอนที่กฏแบบนี้จะสามารถเปลี่ยนแปลงได้ในอนาคต เราจะต้องคุยกับ Domain Expert มาก่อน

เราต้องคุยกับ Domain Expert (ให้รู้เรื่อง)

มี stereotype ของคนที่เรียนจบคอมพิวเตอร์เสมอว่าคุยกับคนอื่นไม่ค่อยรู้เรื่อง ผมจึงทำเวนน์ไดอะแกรมเวลาที่ Software Developer ไปคุยกับ Domain Expert นี้ขึ้นมา

ปฏิเสธไม่ได้ว่าสิ่งที่ Software Developer กับ Domain Expert รู้นั้นไม่ตรงกัน ต่างฝ่ายมีความรู้กันคนละอย่าง แต่ผลงาน(ซอฟแวร์)ที่ต้องการเป็นการทำการประสานกันระหว่างทั้งสองฝ่าย การสื่อสารที่มีประสิทธิภาพจึงต้องเกิดขึ้น

Ubiquitous Language

Ubiquitous Language คือศัพท์ที่ใช้ใน Domain-Driven Design เป็นตัวแทนภาษากลางที่ไว้ใช้คุยระหว่าง Software Developer และ Domain Expert ไม่ใช่แค่คุยกันระหว่างประชุมหรือว่าไวท์บอร์ด แต่ต้องเป็นสิ่งที่ Domain Expert เข้าใจ พร้อมๆกับเป็นสิ่งที่อยู่ในโค้ดด้วย ยกตัวอย่างต่อไปนี้

ถ้าเราใส่ origin, destination และ arrival time ลง “Routing Service” มันจะไปหาจุดสิ้นสุดแล้วก็… ยัดลงดาต้าเบส (คลุมเครือและ technical)

ลองเปลี่ยนคำให้ดูกระชับและเข้าใจได้มากขึ้น

origin, destination และข้อมูลอื่นๆ จะเข้าสู่ “Routing Service” และจะได้ “กำหนดการเดินทาง” ที่มีข้อมูลทุกอย่างที่เราต้องการกลับมา

แบบนี้จะเข้าใจได้มากกว่า และมีศัพท์ที่สื่อให้เห็นภาพพร้อมทั้ง 2 ฝ่ายเข้าใจได้ทันที แต่ว่าเราสามารถทำได้ดีกว่านี้

“Routing Service” จะหา “กำหนดการเดินทาง” ที่ตรงกับ “Route Specification”

จะเห็นได้ว่า ถ้าเรามีภาษาและคำศัพท์ที่สื่อความหมายให้เข้าใจได้ทั้งฝั่ง Domain Expert และ Software Developer โดยทุกคนอยู่บนความเข้าใจเดียวกัน จะส่งผลดีต่อการพัฒนาซอฟแวร์เป็นอย่างมาก

การทำ Domain-Driven Design เหมาะสำหรับการพัฒนาซอฟแวร์แบบ Agile ที่สามารถรับฟัง feedback และพัฒนาเป็นแบบ sprint หรือ cycle

Further Reading

รายละเอียดเพิ่มเติมสามารถอ่านได้จาก Domain-Driven Design: Tackling Complexity in the Heart of Software (2003) ที่เขียนโดย Eric Evans ซึ่งหนังสือเล่มแรกที่พูดถึงเรื่องนี้ https://www.goodreads.com/book/show/179133.Domain_Driven_Design

Implementing Domain-Driven Design (2013) โดย Vaughn Vernon ที่ครอบคลุมถึงการบริหารทีมให้เข้าได้กับ DDD ด้วย https://www.goodreads.com/book/show/15756865-implementing-domain-driven-design

--

--