จากที่เคยไปเรียน Domain Driven Design by Roofimon มาตั้งแต่ปี 2019
ซึ่งสรุปไว้ 3 part ดังนี้
- [Part 1] สรุปจากการไปเรียน Domain-Driven Design by Roofimon
- [Part 2] สรุปการเรียน Domain-Driven Design ในเรื่องของการออกแบบ
- [Part 3] ว่าด้วยเรื่องของรูปแบบความสัมพันธ์ระหว่าง Boundary context ใน DDD
โดยในครั้งนี้ก็ได้ไปเรียนอีกรอบหลังจาก COVID-19 จางไป
มีสิ่งที่น่าสนใจเพิ่มเติม และ เติมเต็มหลายอย่าง
มาดูกันว่ามีอะไรบ้าง ?
เริ่มจากกระบวนการสมัคร
เป็นการส่งใบสมัครด้วยการเขียนบทความที่เกี่ยวกับการ
พัฒนา ออกแบบ ทดสอบ software
ไปเพื่อให้ทำการเลือก เผื่อจะมีโอกาสไปเรียนบ้าง
ก็เลยเขียนและส่งบทความไป
ถ้าจำไม่ผิด ผมน่าจะส่งเรื่องของ Race condition problem ไป
มาถึงวันเรียนวันแรก
มาสายเลย !!!
เริ่มด้วยการ unlearn ของสิ่งที่รู้หรือทำมาก่อน
เพื่อให้เราสามารถเรียนรู้สิ่งใหม่ ๆ หรือ อาจจะเก่า เข้าได้ง่ายขึ้น
ลดการนำไปเปรียบเทียบกับสิ่งต่าง ๆ ที่เรารู้มา
เพราะว่า สิ่งที่เราเรียนรู้ครั้งนี้คือ DDD แบบ classical
เป็นความรู้ที่ถูกคิดและสร้างมานานแล้ว
อาจจะมีหลายอย่างที่ดู out-of-date ไป
แต่สิ่งที่เราต้องการคืออะไร ? มันคือแนวคิดและวิธีการในการ tackle หรือ เข้าใจและแก้ไขปัญหานั่นเอง
ดังนั้นเรื่องต่อมาคือ การทำความเข้าใจ
กับปัญหาของการออกแบบ พัฒนา ทดสอบและส่งมอบ software ว่าเป็นอย่างไร
ถ้าเราไม่เข้าใจปัญหา ก็คงไม่สามารถหาวิธีแก้ไขได้
แต่ว่า สำหรับคนที่จะหาวิธีแก้ไขปัญหา มีความรู้อะไรบ้าง ?
มีประสบการณ์ ?
อ่านหนังสืออะไรกันบ้าง ?
เช่นเรื่อง DDD อ่านหนังสืออะไร ทำอะไร ?
โดยใน course นี้มีหนังสือแนะนำคือ Learning Domain-Driven Design
มีแจกหนังสือด้วยนะ เรียนไปอ่านไปหลาย ๆ คน ก็สนุกดี
ได้แบ่งปันกันในหลาย ๆ มุมมอง
ที่น่าสนใจคือ ไม่ว่าจะเรื่องของ Microservices และ Security ต่าง ๆ นั้น
มักจะมีการอ้างถึงในเรื่องต่าง ๆ
ทั้ง การจัดการ Organization, Technology
และมีเรื่องของ DDD เพื่อทำความเข้าใจกับปัญหาเสมอ
ดังนั้นจึงเป็นสาเหตุว่า ทำไมเราต้องรู็และเข้าใจ DDD นั่นเอง
ในวันแรกจะชี้ให้เห็นว่า สิ่งที่เราต้องเข้าใจว่าตอนนี้เรากำลังทำอะไร
แบ่งเป็น 2 ส่วนของ
- Problem space
- Solution space
โดยเราจะเริ่มที่ Problem space หรือเข้าใจปัญหาก่อนนั่นเอง
ถ้าใน DDD มันก็คือ Strategic design
ส่วน Solution space คือ Tactical design นั่นเอง
เห็นไหมว่า มันคือเรื่องเดียว
ต่างแค่ชื่อเรียกและวิธีการเท่านั้นเอง
ดังนั้นจึงเริ่มด้วยการทำความเข้าใจปัญหา
ด้วยทำ modeling ปัญหาออกมา เพื่อให้ง่ายต่อการทำความเข้าใจ
รูปแบบของการทำ modeling มีมากมายหลายรูปแบบ เช่น
- การจดสรุป เช่น minute meeting
- การเขียน diagram ต่าง ๆ ทั้ง UML, ER เป็นต้น
- การเขียนเป็น flow/journey ต่าง ๆ
- การเขียนใน digital tool ต่าง ๆ
- ดารเขียนเอกสาร
ในแต่ละปัญหาควรมี modeling หลาย ๆ แบบ
เพื่อทำให้เห็นและเข้าใจถึงปัญหานั้น ๆ ในหลาย ๆ มุมมอง
พร้อมแนวทางในการแก้ไขปัญหา
เรียกว่า Model-Driven Design (MDD)
DDD จะเน้นไปที่ 3 เรื่องคือ
- Domain modeling
- Boundary context
- Ubiquitous Language (UL)
เพื่อทำให้เข้าใจ จึงลงมือทำ workshop ทั้งสองวัน มีขั้นตอนดังนี้
- ทำความเข้าใจเกี่ยวกับ flow หรือ journey ของระบบงานแบบ end-to-end เพื่อให้เห็นภาพรวมของการทำงาน
- ตรงนี้แต่ละทีมก็ต้อง modeling สิ่งที่ได้รับมา เพื่อให้เข้าใจและทำการ review ต่อไป
- ทำการแบ่งกลุ่มของขั้นตอนต่าง ๆ ใน flow ที่ทำการ modeling ขึ้นมา วิธีการแบ่งกลุ่มแบบง่าย ๆ คือ actor หรือผู้ใช้งาน และ UL ที่ใช้งานนั่นเอง
- จากนั้นทำการแยกแยะว่าส่วนงานต่าง ๆ ใน flow นั้น อะไรคือ core, generic และ supporting domain เพื่อช่วยให้เรา focus ถูกจุด โดยกลุ่มแรกคือ core domain เป็นสิ่งที่เราสนใจ แต่ต่อไปแต่ละกลุ่มอาจจะเปลี่ยนไปได้ ตาม business ที่เปลี่ยนไปนั่นเอง
- ในแต่ละ domain เราสามารถดูรูปแบบในการติดต่อสื่อสารกันได้ โดยมีหลายรูปแบบ จะเรียกว่า context mapping เช่น separate way, customer-supplier, conformist, anti-corruption layer(ACL), open-host และ publish language
- ในส่วนของ core domain เราก็มาลงรายละเอียดกัน โดยเริ่มจากการวาดรูปของ wireframe หรือหน้าจอของการทำงาน เพื่อให้ทุกคนในทีมเข้าใจได้ง่ายขึ้น
- แนะนำให้เขียนคำหรือภาษาที่ในแต่ละ core domain ใช้งานกัน หรือ UL นั่นเอง เพื่อให้ตรงกับกลุ่มคนจริง ๆ พูดง่าย ๆ คือ business language นั่นเอง เพื่อให้แต่ละฝ่ายในทีมคุยในภาษาเดียวกัน ดังนั้นในทีมควรมี Domain expert ด้วยเสมอ
- ทำการเขียน command และ event ต่าง ๆ ออกมา เพื่อให้เห็นว่า แต่หน้าหน้าจอนั้น ผู้ใช้งานทำ action อะไร และเกิดอะไรขึ้นมาบ้าง ใน core domain นั้น ๆ
- จากนั้นในแต่ละ command, event จะต้องใช้งาน model หรือข้อมูลอะไรบ้าง จากนั้นหา aggregate root ของ model ยกตัวอย่างเช่น ใบสั่งซื้อ เป็น aggregation root ประกอบไปด้วย entity ต่าง ๆ เช่น seller, buyer, product และ payment เป็นต้น โดยในแต่ละ aggregate root นั้นจะจบในตัวเอง ไม่ผูกมัดกับใคร มันคุ้น ๆ ไหม เหมือนอะไร
- ในแต่ละ aggregate root นั้นเราสามารถมองได้ทั้ง logical view หรือ physical view ได้ เช่นกัน นั่นคือ อาจจะรวมกันเป็นรูปแบบของ modular หรือ แยก service ออกจากกันก็ได้ อยู๋ที่การตัดสินใจเลือก ซึ่งมีทั้งข้อดีและข้อเสีย
- การติดต่อสื่อสารของ aggregate root ก็สามารถนำ context mapping มาใช้ได้อีกเช่นเดียวกัน
- ในแต่ละ aggregate root เราสามารถนำมาเพิ่มต่อในส่วนของ tactical design ว่าจะสร้างอย่างไร มีโครงสร้างอย่างไร เช่น MVC, Hexagonal หรือ Clean architecture รวมทั้งจะเข้าใช้งานผ่าน interface อะไร เช่น REST/gRPC หรือ Pub/Sub รวมทั้งการติดต่อไป external database และ service ต่อไป
จะเห็นได้ว่า ก่อนที่เราจะลงไปที่ solution หรือ technical หรือ technology ต่าง ๆ
ควรต้องรู้และเข้าใจปัญหาอย่างแท้จริงก่อนเสมอ
จะได้แก้ไขให้ถูกที่ถูกจุด หรือ เกาตรงที่คันจริง ๆ
ปล. ยังมีรายละเอียด และ คำถามต่าง ๆ ใน workshop ที่น่าสนใจอีกเยอะเลย