Core Concepts of Domain-Driven Design
คำตอบและหมุดเชื่อมโยง: คำว่า "Core concepts of Domain-Driven Design" ตั้งขึ้นเพื่อรวบรวม "อิฐบล็อกพื้นฐานในการสร้างซอฟต์แวร์" (Ubiquitous Language, Value Objects, Entities, Aggregates, และ Bounded Contexts)
สาเหตุที่ระบบซอฟต์แวร์ส่วนใหญ่มีช่องโหว่ความปลอดภัย ไม่ใช่เพราะโปรแกรมเมอร์สะเพร่าทางเทคนิคเสมอไป แต่เกิดจาก "การข้ามพรมแดนทางความหมาย (Semantic Boundaries) และโมเดลที่ไม่รัดกุม" การเข้าใจแนวคิดหลักของ DDD ช่วยให้เราสร้างโมเดลที่นิยามขอบเขตของระบบอย่างชัดเจน และเมื่อระบบถูกบีบให้นิยามชัดเจนว่า "ทำอะไรได้บ้าง" สิ่งที่ระบบ "ห้ามทำ" (ซึ่งก็คือช่องโหว่ความปลอดภัย) จะถูกกำจัดออกไปโดยอัตโนมัติ!
Day 1: Security as a Concern (คดีตู้นิรภัย) / Day 2: The Anti-Hamlet (-1 เล่ม) และความสูญเสียจาก Shallow Modeling
Day 3 จาก 14 วัน — เริ่มต้น Part 2: Fundamentals (รากฐานโครงสร้างระดับสถาปัตยกรรมและโค้ด)
เข้าใจอาวุธหลักทั้ง 5 ชิ้นของ DDD เพื่อนำไปใช้สร้างอิฐบล็อกสยบช่องโหว่ความปลอดภัยในโค้ดตั้งแต่วันถัดๆ ไป (Day 4–7)
เรื่องราวและมโนทัศน์เชิงลึก (The Denver Airport Case & 5 Core Tools)
📖 เรื่องราวจริงทางประวัติศาสตร์
ในช่วงปี ค.ศ. 1990 สนามบินสากลเดนเวอร์ (Denver International Airport) สหรัฐอเมริกา ทุ่มงบประมาณมหาศาลสร้างระบบจัดการกระเป๋าเดินทางอัตโนมัติ (Automated Baggage System) เพื่อรองรับเที่ยวบินขนาดใหญ่
🧠 ถอดรหัสสู่โลกซอฟต์แวร์และ Security (Mental Model)
🗣️ Ubiquitous Language
ภาษาที่ถูกตกลงและใช้ร่วมกันอย่างเคร่งครัดโดยทุกคนในทีม ทั้ง Domain Experts, Developers, Testers, ในเอกสาร, ซอร์สโค้ด, Database และบนหน้าจอ UI
🧱 Value Objects
วัตถุที่ ไม่มี Identity (ไม่มี ID) นิยามความมีตัวตนด้วย "มูลค่า/ค่าของมันเอง" สองวัตถุที่ค่าเท่ากันถือว่าเป็นวัตถุเดียวกัน และ ต้อง Immutable เสมอ
🆔 Entities
วัตถุที่มี Identity ชัดเจนและต่อเนื่องตลอด Life Cycle แม้ Attributes อื่นๆ ภายในจะถูกแก้ไขเปลี่ยนแปลงไปตามกาลเวลาก็ตาม (Mutable State)
📦 Aggregates & Roots
ขอบเขตเชิงมโนทัศน์ (Conceptual Boundary) ที่รวม Entities และ Value Objects เข้าด้วยกัน มี Aggregate Root เป็นประตูทางเข้าเดียวที่ภายนอกอ้างอิงได้
car.steer() ห้ามเดินไปฉีดน้ำมันเข้าห้องเผาไหม้เอง!🗺️ Bounded Context & Semantic Boundary
ขอบเขตที่กำหนดว่า Ubiquitous Language และโมเดลมีความหมายสมบูรณ์และถูกต้องอยู่แค่ภายในพื้นที่นั้น เมื่อก้าวข้าม Bounded Context ความหมายของคำจะเปลี่ยนไปทันที
"Data crossing a semantic boundary is a major security risk" การส่งข้อมูลข้าม Bounded Context โดยไม่มี Translation Layer มักทำให้กฎความปลอดภัยเล็ดลอดและเกิดการแฮกเชิงตรรกะ
แบบฝึกหัดปฏิบัติตามสถานการณ์จริง (Hands-on Refactoring)
// โค้ดเดิม: Customer เป็นเพียงถุงใส่ข้อมูล ไร้ขอบเขต Aggregate public class Customer { public String id; public String name; // ช่องโหว่ใหญ่: เปิด Public Collection ให้ภายนอกแอบแก้! public List<Address> addresses = new ArrayList<>(); } public class OrderService { public void changeShippingAddress(Customer customer, Address newAddress) { // แอบแก้ไข Address ใน Customer จากภายนอกโดยไม่ผ่าน Invariants! customer.addresses.clear(); customer.addresses.add(newAddress); } }
customer.addresses.clear() ลบที่อยู่ทิ้งได้โดยที่คลาส Customer ไม่สามารถคัดค้านได้เลย
// 1. Value Object: Address เป็น Immutable และ Conceptual Whole public final class Address { private final String street; private final String zipCode; private final String city; public Address(String street, String zipCode, String city) { this.street = notEmpty(street, "Street required"); this.zipCode = notEmpty(zipCode, "ZipCode required"); this.city = notEmpty(city, "City required"); } // มีแต่ getters เท่านั้น ไม่มี setters! } // 2. Aggregate Root: Customer ปกป้อง Invariants ควบคุมทางเดียว public class Customer { private final CustomerId id; // Identity private String name; private final List<Address> addresses = new ArrayList<>(); public Customer(CustomerId id, String name, Address primaryAddress) { this.id = notNull(id); this.name = notEmpty(name); this.addresses.add(notNull(primaryAddress)); } // Encapsulated Domain Operation แทนการเปิด List ให้แก้ public void updatePrimaryAddress(Address newAddress) { notNull(newAddress, "New address cannot be null"); this.addresses.set(0, newAddress); } // ส่งออกเฉพาะ Unmodifiable List ป้องกันภายนอกแอบแก้ไข public List<Address> addresses() { return Collections.unmodifiableList(addresses); } }
addresses.clear() ได้อีกต่อไป เพราะคืนค่าเป็น unmodifiableList และการอัปเดตต้องสั่งผ่าน updatePrimaryAddress() ของ Aggregate Root เท่านั้น!
ชุดควิซประเมินความรู้ประจำวัน
ตอบปุ๊บ รู้ผลเฉลยทันที พร้อมคำอธิบายและหลอดพลังงาน Energy Charge
ทดสอบความรู้ Day 3 สำเร็จแล้ว!
สรุปการเชื่อมโยงกลับสู่ Chapter 3 — Core concepts of Domain-Driven Design
เครื่องมือทั้ง 5 ชิ้น (Ubiquitous Language, Value Objects, Entities, Aggregates, และ Bounded Contexts) ในบทนี้ ล้วนตอบคำถามหัวข้อบทอย่างชัดเจนว่า การเข้าใจแนวคิดหลักของ DDD คือหัวใจของการสร้างระบบที่ปลอดภัย เพราะเมื่อเราแบ่งขอบเขตด้วย Bounded Context, ใช้ Ubiquitous Language สื่อสารอย่างตรงไปตรงมา, ปกป้องสถานะด้วย Aggregate Root, และล็อกค่าด้วย Value Objects ตัวโครงสร้างการออกแบบเหล่านี้เองที่จะทำหน้าที่เป็นเกราะคุ้มกันความปลอดภัยที่ทนทานที่สุดให้แก่ซอฟต์แวร์ของเราครับ!