🛑 1. The Trap: "Folder Based on Technology"
คนส่วนใหญ่มักเริ่มสร้างโปรเจกต์ NestJS โดยการแยกโฟลเดอร์ตามประเภทของไฟล์ เช่น controllers, services, entities:
- ปัญหา: เมื่อโปรเจกต์โตขึ้น มี 50 Controllers อยู่ในโฟลเดอร์เดียว คุณจะหาโค้ดไม่พบ และทุกอย่างจะพันกันจนแยกไม่ออก (Tight Coupling)
Senior Solution: เราต้องเปลี่ยนจากการจัดโฟลเดอร์ตาม "เทคโนโลยี" มาเป็นการจัดตาม "ธุรกิจ" หรือที่เรียกว่า Domain-Driven Design (DDD) ครับ
💡 2. Real-Life Analogy: ห้องครัวร้านอาหาร vs โรงอาหารโรงเรียน
- โฟลเดอร์แบบเดิม (Technical Split): เหมือนคุณเก็บ "มีดทุกเล่ม" ไว้ในลิ้นชักเดียว "เขียงทุกอัน" ไว้อีกลิ้นชัก พอจะทำซูชิ คุณต้องเดินวุ่นไปทั่วครัวเพื่อหยิบของที่กระจัดกระจาย
- โฟลเดอร์แบบ DDD (Domain Split): เหมือนการแยก "สเตชัน". สเตชันซูชิมีครบทั้งมีดสำหรับปลาและเขียงเฉพาะทาง ทุกอย่างที่เกี่ยวข้องกับการทำซูชิรวมอยู่ที่เดียว (Encapsulation)
- บทสรุป: เมื่อธุรกิจต้องการเพิ่มเมนู "สเต็ก" คุณแค่เพิ่มสเตชันใหม่ โดยไม่กระทบกับสเตชันซูชิเดิมครับ
🚀 3. Execution Journey: ขั้นตอนการจัดโครงสร้างแบบ Domain-First
ในโปรเจกต์ Aura Tour Booking ผมไม่ได้มองแค่ว่ามี Table อะไรบ้าง แต่มองว่ามี "Domain" อะไรบ้าง:
🛠 Step-by-step:
- Identify Domains: แยกส่วนงานที่อิสระจากกัน เช่น
Tours,Bookings,Users,Payments - Module Encapsulation: ทุก Domain จะมี Module ของตัวเอง ซึ่งภายในจะมี Controller, Service และ Entity ที่ทำงานร่วมกันเท่านั้น
- Communication via Interfaces: ถ้า
Bookingsต้องการข้อมูลจากToursต้องคุยผ่าน Service ที่ Export ออกมาเท่านั้น ห้ามแอบไปยิง Database ข้ามเครื่องกันเอง
// ✅ โครงสร้างโฟลเดอร์แบบ Senior (DDD Lite)
src / tours / tours.controller.ts;
tours.service.ts;
tours.module.ts;
entities / tour.entity.ts;
bookings / bookings.controller.ts;
// ...
🪤 4. The Junior Trap: "Circular Dependency"
เมื่อคุณเริ่มแยก Module จูเนียร์มักจะเผลอเอา Module A เรียก B และ B กลับมาเรียก A:
- ปัญหา: NestJS จะรันไม่ขึ้นเพราะมันงงว่าจะสร้างอะไรก่อน (Infinite Loop)
- ✅ การแก้ไข: จงสร้าง "Shared Module" หรือ "Core Module" สำหรับเก็บสิ่งที่ทุกคนต้องใช้ร่วมกัน หรือใช้ Domain Events (Pub/Sub) เพื่อให้แต่ละ Module ไม่ต้องรู้จักกันโดยตรงครับ
⚖️ 5. The Architecture Matrix: ยิ่งซับซ้อน ยิ่งต้องใช้วินัย
| หัวข้อ | Simple CRUD (Junior) | Professional DDD (Senior) |
|---|---|---|
| ความเร็วในตอนเริ่ม | 🚀 เร็วมาก | 🐢 ช้ากว่า (ต้องวางแผน) |
| ความง่ายในการแก้ Bug | 😱 ยาก (เพราะโค้ดพันกัน) | ✅ ง่าย (แก้แค่ใน Domain นั้น) |
| การทำ Unit Test | ยาก (ต้อง Mock มหาศาล) | ✅ ง่ายมาก (Scope ชัดเจน) |
| การขยายทีม | ทุกคนแก้ไฟล์เดียวกัน | แยกกันทำงานตาม Domain ได้เลย |
🎓 6. Senior Mindset Summary
การเขียนโค้ดให้ "รันได้" ใครๆ ก็ทำได้ แต่การรักษาโค้ดให้ "อ่านออกและแก้ได้" หลังจากผ่านไป 2 ปี นั่นคือหน้าที่ของ Senior ครับ การใช้ DDD ไม่ใช่แค่การจัดโฟลเดอร์ แต่คือการมัดรวม Business Logic กับ Technical Implementation ให้เดินไปในทิศทางเดียวกันครับ!