DDD, TDD, BDD มันคืออิหยังนะ
Software development methodologies ถูกคิดค้นขึ้นเพื่อช่วยให้ Dev ส่งมอบโค้ดได้ราบลื่นและมีข้อบกพร่องน้อย ซึ่งช่วงนี้จะมีการพูดถึงบ่อย ๆ 3 ตัว ได้แก่ Domain Driven Design (DDD), Test Driven Development (TDD) และ Behavior Driven Development (BDD) แม้ว่าชื่อจะคล้ายกัน แต่วิธีการเหล่านี้มีความแตกต่างกัน ซึ่งจะเปรียบเทียบ DDD, TDD และ BDD ดูตามความเข้าใจแบบคนขี้เกียจได้ประมาณนี้
Domain Driven Design (DDD)
หลักการ
DDD จะเป็นการการออกแบบโมเดลทางธุรกิจออกเป็น Domain เพื่อลดการเกิดโมเดลของตัว sofware ออกแบบหรือทำออกมาแล้วไม่สอดคล้องกับ business domain ตย. ง่าย ๆ เลยคือ เมื่อทำงานไปทำงานมาตอนจะจบงาน มันจะมี tables, fields งอกขึ้นมาพันกัน หรือ ไม่ได้ใช้งานจริง ๆ เต็มไปหมด
- มุ่งเน้นไปที่ Core Domain และ logic ของแต่ละ domain
- Dev ทำงานร่วมกับ Domain expert (ผู้ที่เข้าใจใน business ของตัว product)
- สร้างแบบจำลองการพัฒนาของโดเมน
- คุยกันด้วย “ภาษาที่เข้าใจง่าย” ที่สมาชิกในทีมทุกคนเข้าใจ
- แบ่งแยกความซับซ้อนผ่านขอบเขตของ domain
แนวปฏิบัติ
DDD อาศัยการสร้างแบบจำลองโดเมนเป็น entities, value objects, aggregates และ bounded contexts ซึ่ง Dev จะต้องทบทวน models และ domains อย่างต่อเนื่องเพื่อปรับความเข้าใจในสิ่งที่แต่ละ domain ที่รับผิดชอบ
- เริ่มด้วยการแบ่ง event ของแต่ละ domain โดย domain expert ทริกคือคำที่ใช้เรียกสิ่ง ๆ นึงจะเปลี่ยนไปในแต่ละ event เช่น user ที่มีได้หลายสถานะตามแต่ event ของ domain ตย. ผู้เยี่ยมชม -> สมาชิก -> ลูกค้า -> ลูกหนี้ -> ผู้รับพัสดุ
- จะต้องใช้ภาษาที่เข้าใจกันง่ายที่สุด ทั้งฝั่ง business และ tech
- กำหนดขอบเขตของแต่ละ domain เช่น เมื่อ user ทำการชำระเงิน ใน domain payment แล้วเข้าสู่ domain delivery
- สำรวจทบทวนหา sub domain โดยออาจจะจำลองขึ้นมา เช่น ใน doamin payment อาจจะมี sub domain เป็น debit, credit, reconcile ที่รับผิดชอบ payment ร่วมกัน แต่การทำงานรับผิดชอบต่างกัน
กรณีการใช้งาน
DDD มีประโยชน์มากที่สุดสำหรับโดเมนธุรกิจที่ซับซ้อนซึ่งต้องใช้ตรรกะที่ซับซ้อน DDD ให้โครงสร้างความซับซ้อนของโดเมนแยกออกมาชัดเจน
DDD เหมาะสำหรับ
- ระบบการเงิน
- การสมัครประกันภัย
- ระบบด้านการดูแลสุขภาพ
- Domain อื่นๆ ที่มีวิธีการทางธุรกิจที่เปลี่ยนแปลงอยู่ตลอดเวลา
ข้อจำกัดของ DDD
- learning curve เกี่ยวกับรูปแบบและหลักการทางวิธีทำสูง ต้องอาศัย ปสก. เข้าช่วย
- ยากที่จะระบุ domain, context, layer ได้อย่างถูกต้อง
- การสร้างแบบจำลองจำเป็นต้องมีการวิเคราะห์ล่วงหน้าและการทำซ้ำทบทวนเพื่อให้แม่นยำและเข้าใจถูกต้อง
Test Driven Development (TDD)
หลักการ
TDD จะเข้าไปอยู่ใน loop การ dev โดยที่ requirement จะถูกแปลงเป็น test case เฉพาะ function นั้น ๆ จากนั้นโค้ดจะถูกเขียนขึ้นมาเพื่อให้ ผ่าน test case
- เขียน test ก่อนที่จะ coding functions ใด ๆ
- เขียนโค้ดให้เพียงพอที่จะผ่านการทดสอบเท่านั้น ไม่ over engineering
- refactor โค้ดเป็นเรื่องปกติ
- ทำให้ test case และ coding เรียบง่ายที่สุด
แนวปฏิบัติ
- เขียน test case ขึ้นมาตาม requirement
- สั่ง test เพื่อดูว่า test ทำงานได้ซึ่งในครั้งแรกจะต้อง fail (red)
- เขียนโค้ดเพื่อผ่านการทดสอบ (green)
- refactor, comment, optimized ตามที่จำเป็น (refactor)
- ทำซ้ำวนไปจ้า
ซึ่งอาจจะดูเหมือน loop นรก แต่ว่าหากเราทำแต่พอดี ไม่ over engineering จะพบว่าในทุก ๆ การต่อเติมเราจะมี test กำกับไม่ทำให้ของเดิมพังแบบไม่รู้ตัว
กรณีการใช้งาน
TDD จะเข้าได้ดีกับการทำงานเป็น function แล้วจบไป การทดสอบการเขียนจะบังคับให้ dev ได้ทบทวนทำความเข้าใจ requirement ก่อนจะ coding (ก็แน่หล่ะ โดนบังคับเขียน test case ตาม requirement) ซึ่งผลพลอยได้คือ technical docs จาก test case และ คุณภาพของงานที่มีข้อบกพร่องน้อยลง (ถ้า test case ไม่ผิดละนะ)
TDD เหมาะสำหรับ
- งาน back-end (API, microservices)
- function ตาม business logic
- อะไรก็ตามเป็น function ที่มีการต่อเติมหรือใช้งานซ้ำ ๆ
ข้อจำกัดของ TDD
- ต้องใช้เวลาไปกับการเขียน test ก่อนการ coding
- งานจะดีไม่ดีขึ้นอยู่กับความชำนาญในการเขียน test (อาจจะแก้ขัดได้ด้วย senior ช่วยเขียน test ให้ก่อนแล้วให้ junior เขียน function)
- จะไร้ประโยชน์ไปเลยถ้า requirement ยังไม่นิ่ง เพราะจะเสียเวลาไปกับ loop การเขียน test และ coding ใหม่ อันนี้ต้องไป Behavior Driven Development (BDD)
Behavior Driven Development (BDD)
หลักการ
BDD มุ่งเน้นไปที่การกำหนดพฤติกรรมของระบบในลักษณะที่ทั้งฝั่ง business และ tech เข้าใจร่วมกัน
- test case เขียนเป็นภาษาที่เข้าใจทั้ง business และ tech
- test case เขียนขึ้นด้วยโดยผลลัพธ์ทาง business ไม่ใช่รายละเอียดทางเทคนิคที่ใช้พัฒนา
- ทีม business และ tech ทำงานร่วมกันตาม requirements
- requirements จะถูกแปลงมาเป็น automated regression tests
แนวปฏิบัติ
BDD นำทีม business และ tech มารวมกันเพื่อกำหนดพฤติกรรมของระบบ โดยจะร่วมมือกันเขียน script พฤติกรรมของระบบที่คาดหวังโดยจะมีหัวข้อลำดับตามนี้
- Given [บริบท]
- When [เหตุการณ์เกิดขึ้น]
- Then [ผลลัพธ์ที่คาดหวัง]
ซึ่ง script เหล่านี้จะอธิบายลักษณะการทำงานของ function ทั้งหมด แทนที่จะเป็นเพียงรายละเอียดทางเทคนิค ซึ่งการทดสอบจะเป็น automated regression tests
กรณีการใช้งาน
BDD ช่วยให้เกิดการมีส่วนร่วมระหว่าทีม business และ tech ซึ่งช่วยให้ทุกคนเข้าใจ requirement ร่วมกันล่วงหน้าก่อนที่จะเริ่ม coding
BDD เหมาะสำหรับ
- Web App/Mobile App หรือส่วนที่ติดต่อกับ Users
- Project ที่มี requirement ไม่นิ่ง
- Project ที่ผู้มีส่วนร่วมใน project ไม่เชี่ยวชาญด้านเทคนิคทุกคน
ข้อจำกัดของ BDD
- ต้องใช้เวลาล่วงหน้ามากขึ้นสำหรับการทำงานร่วมกันและการเขียน test
- ดูจะยุ่งยากถ้าเอาไปใช้กับงาน back-end
สรุป
- DDD มุ่งเน้นไปที่การสร้างแบบจำลองโดเมนธุรกิจที่ซับซ้อนให้ออกมาเป็น model ที่เหมาะกับการ dev
- TDD มุ่งเน้นไปที่ coding และคุณภาพของงาน ไม่ให้ dev ของใหม่แล้วของเก่าพัง
- BDD มุ่งเน้นไปที่การกำหนดลักษณะการของระบบ ไม่ให้ dev หลงทาง
วิธีการทั้ง 3 สามารถเอามาใช้ร่วมกันได้ขึ้นอยู่กับว่าจะปรับใช้กับเทคนิคแบบไหนให้เหมาะสมกับงาน