พอดีช่วงบ่ายวันศุกร์เห็น course Domain-Driven Design by Roofimon เด้งขึ้นมา
ลองไปกดดู ก็มีบัตรว่างด้วย
ดังนั้นจึงซื้อตั๋วไปเรียนด้วย
เป้าหมายหลัก ๆ เพื่อทำให้รู้และเข้าใจเกี่ยวกับ DDD (Domain-Driven Design)
ว่าคืออะไร เป็นอะไร
มาเริ่มกันเลย

เป้าหมายของ course นี้ประกอบไปด้วย

  • ที่ไปที่มาของแนวคิด DDD
  • Principles ต่าง ๆ
  • วิธีการในการทำ Modeling หรือ Model-Driven Design ซึ่งมีหลายรูปแบบ
  • วิธีการทำงานร่วมกันหรือ collaboration
  • อธิบายถึงแนวคิด CQRS(Command Query Responsible Segregation) และ Event sourcing

จะเน้นไปที่แนวคิด การออกแบบ การทำงานร่วมกัน
ส่วนการ implementation หรือพวก technical จะไม่เน้น

เข้าใจที่ไปที่มาของ DDD จากรูปแบบการออกแบบ software กัน

เริ่มต้นด้วยแนวทางการออกแบบเดิม ๆ
หรือการออกแบบในการทำงานแบบ Waterfall นั้น
พยายามให้ทีมออกพยายามทำการออกแบบ
ในขณะที่มีความรู้ใน domain หรือเรื่องนั้น ๆ น้อยมาก
(ยกเว้นว่ามีความรู้ด้านนั้น ๆ มานานและมากแล้ว)
ทำให้การออกแบบออกมาในรูปแบบหนึ่งซึ่งก็สามารถทำงานได้ดี !!

แต่เมื่อเรามีความรู้มากขึ้น
ระบบงานใหญ่ขึ้น หรือมีความซับซ้อนมากขึ้น
พบว่าสิ่งที่ออกแบบและทำมานั้น
มันเริ่มไม่เหมาะสม
สัญญาณที่บอกว่า ไม่เหมาะสม ก็เช่น 
พัฒนาได้ช้า  เกิด side-effect เยอะ และ deploy มีพิธีกรรมเยอะ  !!

ยกตัวอย่างสิ่งที่เห็นได้ชัดเจนก็เช่น

Database มีจำนวน table เยอะมาก ๆ
เมื่อต้องการใช้ข้อมูลจำเป็นต้องเขียนคำสั่ง SQL ที่ยาวเหยียด
มันเป็นการบ่งบอกถึงปัญหาว่า
จำนวน table เยอะเกินไป หรือ fragmentation มากไปนั่นเอง
สาเหตุหลัก ๆ ของปัญหานี้คือ

  • เรานำข้อมูล master, transactional และ analytical มาจัดเก็บไว้ที่เดียวกัน
  • สนใจเรื่องของ consistency หรือความถูกต้องของข้อมูลมากจนเกินไป (Over consistency)

คำถามคือ ปัญหานี้แก้ไขด้วยวิธีการอะไร ?

คำตอบคือ 
ก็มีการใช้งาน Store procedure ไงละ
สำหรับจัดการ process การทำงานที่ซับซ้อน

ส่วนถ้าต้องเขียน SQL การดึงข้อมูลเยอะ ๆ ก็ยัดเข้าไปใน View เลย

ส่วนถ้ามีข้อมูลเกิดขึ้นที่หนึ่ง แล้วต้องไปเพิ่มข้อมูลอีกที่หรืออีก table ก็ใช้ Trigger ไงละ  เป็นไงละ reactive ไหมละ

ซึ่งทั้งหมดนี้ทำงานอยู่ใน Database Server นั่นเอง !!
แน่นอนว่า มันเร็วมาก ๆ แต่เมื่อเวลาผ่านไป ระบบใหญ่ขึ้น Business logic เยอะขึ้น
พบว่า Database Server หรือ RDBMS (Relational Database Management System) ใหญ่
และซับซ้อนมาก (Overuse RDBMS)
คุ้นกันไหม ? กับระบบงานที่หลาย ๆ คนยังต้องดูแลกันอยู่ไหมนะ

คำถามคือ ปัญหานี้แก้ไขด้วยวิธีการอะไร ?

คำตอบคือ 
จากเดิมที่ business logic อยู่ใน Database Server ซึ่งมีปัญหา
ดังนั้นแยกออกมาดีกว่า
เอามาใส่ใน Presentation หรือ Web หรือ Business tier
ตาม Architecture แบบ N-Tier
หรืออาจจะออกแบบตามแนวคิดของ SOA (Service-Oriented Architecture)
หรือไปจนถึง Microservices

แต่ผลสุดท้ายแล้วยังเกิดปัญหาเดิม ๆ คือ
Database Server ยังไมีขนาดใหญ่
จำนวน table มากมาย
ถ้า Database Server พังไป ส่งผลกระทบให้ระบบหลัก ๆ พังหมด

สุดท้ายระบบงานก็มักเกิดปัญหา หรือ วิกฤติของการพัฒนา software (Software Crisis)

ทั้งพัฒนาไม่ทันเวลาที่กำหนด หรือ ที่สัญญาไว้
ทั้งพัฒนาระบบงานแย่ ๆ ออกมา 
ทั้งส่งระบบงานช้า
ทั้งใช้ resource เยอะ
ทั้งพังบ่อย
ทั้งยากต่อการแก้ไข หาปัญหา
ก่อให้เกิดความไม่ไว้ใจซึ่งกันและกัน

จากปัญหาที่เกิดขึ้น จึงมีแนวคิดต่าง ๆ ในการแก้ไขขึ้นมา

ยกตัวอย่างเช่น

  • Extreme Programming (XP) เกิดจากการมองว่าปัญหาเกิดจากนักพัฒนา จึงแก้ไขที่วิธีการของนักพัฒนา ทั้ง TDD, CI, Review code และ Collective Ownership
  • Scrum เกิดจากมุมมองด้านของ Project management สำหรับการปรับปรุงขั้นตอนการทำงานขององค์กรณ์ให้เรียบง่ายมากขึ้น ด้วยการมีเพียงแค่ 3 roles เท่านั้น
  • Kanban เกิดจากมุมมองของการทำงานร่วมกัน

แต่แนวคิดและวิธีการต่าง ๆ เหล่านี้
ไม่ได้บอกหรืออธิบายการออกแบบ Architecture ของ software เลย
มีเพียงการบอกว่า Architecture ที่ดีมันจะออกมาแบบ Iterative and Incremental หรือค่อยเป็นค่อยไปตามความต้องการ หรืออาจจะเรียกว่า Emergent Design
ผลที่ได้ออกมาคือ เหมือนเดิม
ได้ระบบออกมาลักษณะเดิม แต่จัดการได้ดีขึ้น
เช่น ส่วน UI มีการทดสอบที่ดี
ส่วนของ business มีการทดสอบที่ดี
แต่ส่วนของ Database ยังไม่ขนาดใหญ่

เพราะอะไรจึงเป็นเช่นนี้ ? (Missing Pieces)

สิ่งที่เรายังขาดหายไปจากแนวคิดต่าง ๆ คือ 
ความรู้ในเรื่องของ Software Architect ว่าต้องทำอะไร อย่างไร
เพื่อให้ระบบมันสามารถพัฒนาไปเรื่อย ๆ ได้
จะทำอย่างไรให้ปรับเปลี่ยนไปตามความต้องการได้
จะทำอย่างไรให้มันดูแลรักษาได้ง่าย

Image result for missing piece

เราจึงต้องการแนวทางและวิธีการในการออกแบบ Software Achitecture
ที่มีประสิทธิภาพ ไม่ over engineering เกินไป ดังที่เคยเกิดขึ้น
บ่อยครั้งมักได้ยินว่า ออกแบบอะไรมา ไม่ตรงความต้องการเลย
แต่ต้องทำตาม ทำไมนะ ?
นั่นคือ วิธีการที่ทำมานั้นไม่มีประสิทธิภาพ

หนึ่งในวิธีการที่น่าจะมีประสิทธภาพคือ DDD (Domain-Driven Design)

แต่วิธีการเดียวไม่น่าจะเพียงพอ
ดังนั้นจึงจำเป็นต้องนำเอาวิธีการต่าง ๆ มาประยุกต์ใช้งานร่วมกัน
ยกตัวอย่างเช่น

  • Architecture นำแนวคิด DDD มาใช้
  • Process การทำงาน นำแนวคิด Scrum มาใช้
  • Coding นำแนวคิด XP มาใช้
  • การทำงานร่วมกัน (Collaboration) นำแนวคิด Kanban มาใช้

ต่อจากนี้เรามาดูกันว่าแนวคิด DDD มันเป็นอย่างไรบ้าง ?