ข้าม​ไป​ยัง​เนื้อหา

EventStorming

เวิร์กช็อปร่วมกัน​เพื่อ​เข้าใจ domain ที่​ซับซ้อน​ผ่าน​เหตุการณ์

EventStorming เป็น​เทคนิค​เชิง​เวิร์กช็อป​ที่​ทรง​พลัง​และ​เน้น​การ​ร่วมมือ ช่วย​ให้​ทีม​เข้าใจ domain ธุรกิจ​ที่​ซับซ้อน​ได้​ลึกซึ้ง​ขึ้น ผู้​เข้า​ร่วม​มา​จาก​ทั่ว​ทั้ง​ธุรกิจ — stakeholder, นัก​พัฒนา, ผู้เชี่ยวชาญ domain, business analyst, designer และ​ใคร​ก็ตาม​ที่​เกี่ยวข้อง

ความ​เจ็บ​ปวด​ของ​การ​พัฒนา​ซอฟต์แวร์​ส่วน​หนึ่ง​มา​จาก​ปัญหา​การ​สื่อสาร — ไซโล ภาษา​ที่​ไม่​ตรง​กัน​ระหว่าง​ทีม EventStorming ช่วย​ข้าม​อุปสรรค​เหล่า​นี้​ด้วย​การนำ​ทุก​คน​มา​อยู่​ใน​ห้อง​เดียวกัน โดย​มี facilitator (ดี​ที่สุด​คือ​คนนอก​ที่​ไม่​ติด​การเมือง​องค์กร) คอย​จุด​บทสนทนา ถาม​คำถาม​ที่​คน​อื่น​อาจ​ไม่​กล้า​ถาม และ​พากลุ่ม​สร้าง timeline ร่วม ของ domain หรือ​กระบวนการ โดย​ใช้ sticky note แทน​เหตุการณ์ (event) และ​องค์​ประกอบ​ต่าง ๆ

Alberto Brandolini เป็น​ผู้​คิดค้น EventStorming ขึ้น​ใน​ปี 2013 โดย​เริ่ม​จาก​การ​มอง​หา​ทาง​เลือก​ที่​เร็ว​กว่า​การ​เขียน UML diagram อย่าง​ละเอียด ชื่อ “EventStorming” เกิด​ขึ้น​ระหว่าง​ที่ Brandolini รับ​เชิญ​เป็น​วิทยากร​ใน IDDD Tour ของ Vaughn Vernon — คำ​ว่า “Event-based” ถูก​ใช้​อยู่​แล้ว​ใน​เอกสาร​ของ Vernon ทำให้​ต้อง​รีแบรนด์​ชื่อ​เทคนิค​ก่อน​ขึ้น​พูด​ที่​เมือง Leuven จน​กลาย​มา​เป็น​คำ​เดียว​คือ “EventStorming”

หัวใจ​ของ​เทคนิค​คือ​การ​ให้​กลุ่ม​คน​เขียน domain event (สิ่ง​ที่​เกิด​ขึ้น​แล้ว​ใน domain ใช้​กริยา​รูป​อดีต เช่น “OrderPlaced”, “PaymentReceived”) ลงบน sticky note สี​ส้ม แล้ว​นำ​มา​เรียง​ต่อ​กัน​บน​กำแพง​ยาว ๆ (ไม่​ต้อง​มี​ที่นั่ง เพื่อ​บังคับ​ให้​ทุก​คน​ยืน​และ​เคลื่อนไหว​รอบ ๆ model) จน​เกิด​เป็น timeline ของ​กระบวนการ​ทาง​ธุรกิจ​ทั้งหมด จาก​นั้น​ค่อย ๆ เพิ่ม​องค์​ประกอบ​อื่น​เข้าไป​ที​ละ​ชั้น​ด้วย​สี​ที่​มี​ความหมาย​ต่าง​กัน — แนวทาง​ที่​ชุมชน ddd-crew สรุป​ไว้​ใน​เอกสาร cheat sheet มี​ดังนี้:

  • Domain Event (สี​ส้ม) — สิ่ง​ที่​เกิด​ขึ้น​แล้ว เขียน​เป็นกริยา​รูป​อดีต
  • Command (สี​ฟ้า) — การ​ตัดสิน​ใจ​หรือ​เจตนา​ที่ actor หรือ​ระบบ​สั่ง​ให้​เกิด​ขึ้น อยู่​ก่อนหน้า domain event ที่​มัน​ก่อ​ให้​เกิด
  • Actor (สี​เหลือง​เล็ก) — บุคคล ทีม หรือ​กลุ่ม​ที่​เกี่ยวข้อง​กับ event
  • Aggregate / Constraint (สี​เหลือง​ใหญ่) — วัตถุ​หรือ​กฎ​ทาง​ธุรกิจ​ที่​ควบคุม​ว่า command ไหน​จะ​ได้​รับ​อนุญาต​ให้​เกิด event ได้
  • Policy (สี​ม่วง​อ่อน) — กฎ​แบบ “เมื่อ X เกิด​ขึ้น ให้​ทำ Y” ที่​เชื่อม domain event หนึ่ง​ไป​สู่ command ถัด​ไป อาจ​เป็น​ระบบ​อัตโนมัติ​หรือ​คน​ทำ​เอง
  • Read Model / View (สี​เขียว) — ข้อมูล​ที่ actor ต้อง​เห็น​ก่อน​ตัดสิน​ใจ​สั่ง command
  • External System (สีชมพู​กว้าง) — ระบบ​ภายนอก​ที่​ยิง command เข้า​มา​หรือ​รับ event ออก​ไป
  • Hotspot (สีชมพู​นีออน วาง​เอียง) — จุด​ที่​มี​ความ​ขัดแย้ง ไม่​แน่ใจ หรือ​คำถาม​ที่​ยัง​ไม่มี​คำ​ตอบ ทำ​เครื่องหมาย​ไว้​เพื่อ​สำรวจ​ภายหลัง​โดย​ไม่​ทำให้ workshop สะดุด

Brandolini แบ่ง​ระดับ​ของ EventStorming ไว้​หลาย​ระดับ ตั้งแต่ Big Picture (มอง​ภาพ​รวม​ทั้ง​องค์กร​หรือ domain เพื่อ​หา pain point และ​ขอบเขต), Process Modeling (ลง​รายละเอียด​กระบวนการ​ที​ละ​ขั้น เห็น actor, policy, hotspot ชัด​ขึ้น), ไป​จนถึง Software Design (ระดับ​ที่​ลึก​พอ​จะ​นำ​ไป​แปลง​เป็น aggregate, bounded context และ code จริง​ได้)

EventStorming ไม่ใช่​แค่​เทคนิค​ระดม​สมอง แต่​เป็น​สะพาน​เชื่อม​ระหว่าง​สอง​ซีก​ของ DDD:

  1. Strategic design — เมื่อ​ทำ Big Picture EventStorming ทีม​จะ​เห็น timeline ยาว ๆ ของ​ทั้ง​องค์กร แล้ว​สังเกต​ได้​ว่า​จุด​ไหน​ภาษา​ที่​ใช้​เปลี่ยน​ไป จุด​ไหน​มี​ความ​เป็น​เจ้าของ (ownership) ต่าง​กัน — นี่​คือ​สัญญาณ​ของ Bounded Context ใหม่ ทำให้ EventStorming กลาย​เป็น​เครื่องมือ​ค้นหา​ขอบเขต​ของ context ที่​รวดเร็ว​กว่า​การ​นั่ง​วิเคราะห์​เอกสาร​ที​ละ​หน้า
  2. Ubiquitous Language — เพราะ​ผู้เชี่ยวชาญ domain เป็น​คน​เลือก​คำ​ที่​เขียน​บน sticky note เอง ไม่ใช่​นัก​พัฒนา​แปล​จาก​ข้อ​กำหนด คำ​ศัพท์​ที่​ได้​จึง​เป็น​ภาษา​กลาง​ที่​แม่นยำ​และ​ทุก​ฝ่าย​เข้าใจ​ตรง​กัน​ตั้งแต่​ต้น
  3. Tactical design — เมื่อ workshop ลง​ลึก​ถึง​ระดับ Software Design, sticky note สี​เหลือง (Aggregate) และ​ลูกศร​จาก Command ไป​ยัง Domain Event จะ​แปลง​ตรง​เป็น code ได้​เกือบ​ทันที: Aggregate รับ Command ตรวจสอบ invariant แล้ว publish Domain Event ส่วน Policy ก็​คือ event handler ที่ subscribe event หนึ่ง​แล้ว​ยิง command ถัด​ไป — สอดคล้อง​โดยตรง​กับ​รูปแบบ Domain Events ใน​เชิง​สถาปัตยกรรม

เอกสาร​ของ Microsoft ที่​อธิบาย​การ​ออกแบบ domain event ใน .NET ก็​ยืนยัน​แนวคิด​เดียวกัน: domain event คือ​สิ่ง​ที่​เกิด​ขึ้น​แล้ว​ใน domain ที่​ส่วน​อื่น​ของ domain เดียวกัน​ควร​รับรู้​และ​ตอบ​สนอง โดย​ชื่อ class ควร​เป็นกริยา​รูป​อดีต​ตาม​ภาษา​ที่​ผู้เชี่ยวชาญ domain ใช้ (ubiquitous language) เช่น​เดียว​กับ​ที่ EventStorming กำหนด​ให้ sticky note สี​ส้ม​ต้อง​เป็นกริยา​รูป​อดีต — เป็น​ตัวอย่าง​ที่​ชัดเจน​ว่า​ผลลัพธ์​จาก workshop ไหล​ตรง​ไป​เป็น​ชื่อ class ใน code ได้​เลย

ข้อดี​อีก​อย่าง​ของ EventStorming ต่อ DDD คือ​มัน​เปิด​โอกาส​ให้​เห็น hotspot — จุด​ที่​ทีม​ยัง​ไม่​เห็น​ตรง​กัน หรือ​กฎ​ธุรกิจ​ที่​ขัดแย้ง​กันเอง — ตั้งแต่​ช่วง​ต้น​ของ​โครงการ ก่อน​ที่​จะ​เขียน code ไป​ผิด​ทาง​แล้ว​ค่อย​มา​แก้​ทีหลัง​ซึ่ง​มี​ต้นทุน​สูง​กว่า​มาก

สมมติ​ทีม​ทำ EventStorming เรื่อง​กระบวนการ​สั่ง​ซื้อ​ของ​ร้าน​ค้า​ออนไลน์ แล้ว​ได้ timeline อย่าง​ง่าย​ดังนี้ (Actor สั่ง Command, Aggregate ตรวจสอบ​แล้ว publish Domain Event, Policy รับ event แล้ว​สั่ง Command ต่อ, Read Model ให้​ข้อมูล​กลับ​ไป​ยัง Actor):

graph LR
    Customer[Actor Customer] --> PlaceOrder[Command PlaceOrder]
    PlaceOrder --> OrderAggregate[Aggregate Order]
    OrderAggregate --> OrderPlaced[Domain Event OrderPlaced]
    OrderPlaced --> ReserveStockPolicy[Policy ReserveStock]
    ReserveStockPolicy --> ReserveStock[Command ReserveStock]
    ReserveStock --> InventorySystem[External System Inventory]
    OrderPlaced --> OrderSummary[Read Model OrderSummary]
    OrderSummary --> Customer

จาก sticky note เหล่า​นี้ ทีม​สามารถ​แปลง​ตรง​เป็น code C# ได้​โดยที่​ชื่อ class ยัง​คง​คำ​ศัพท์​เดียว​กับ​ที่​เขียน​บน​กำแพง:

// Command: มาจาก sticky note สีฟ้า "PlaceOrder"
public sealed record PlaceOrderCommand(Guid CustomerId, IReadOnlyList<OrderLine> Lines);
// Domain Event: มาจาก sticky note สีส้ม เขียนเป็นกริยารูปอดีต
public sealed record OrderPlaced(Guid OrderId, Guid CustomerId, DateTime OccurredOn);
// Aggregate: มาจาก sticky note สีเหลือง ควบคุม invariant ก่อนปล่อย event
public class Order
{
private readonly List<object> _domainEvents = new();
public Guid Id { get; private set; }
public OrderStatus Status { get; private set; }
public static Order Place(Guid customerId, IReadOnlyList<OrderLine> lines)
{
if (lines.Count == 0)
{
// Hotspot ที่พบระหว่าง workshop: "สั่งซื้อออเดอร์ว่างได้ไหม" ทีมตกลงว่าไม่ได้
throw new InvalidOperationException("ออเดอร์ต้องมีอย่างน้อยหนึ่งรายการ");
}
var order = new Order { Id = Guid.NewGuid(), Status = OrderStatus.Placed };
order._domainEvents.Add(new OrderPlaced(order.Id, customerId, DateTime.UtcNow));
return order;
}
public IReadOnlyList<object> DomainEvents => _domainEvents;
}
// Policy: มาจาก sticky note สีม่วง "เมื่อ OrderPlaced เกิดขึ้น ให้ ReserveStock"
public class ReserveStockPolicy : IDomainEventHandler<OrderPlaced>
{
private readonly IInventoryClient _inventory;
public ReserveStockPolicy(IInventoryClient inventory) => _inventory = inventory;
public Task Handle(OrderPlaced domainEvent, CancellationToken cancellationToken)
// ยิง Command ถัดไปไปยัง External System สีชมพู "Inventory"
=> _inventory.ReserveStockAsync(domainEvent.OrderId, cancellationToken);
}

จะ​เห็น​ว่า sticky note แต่ละ​สี​บน​กำแพง​มี​คู่​ตรง​กับ​องค์​ประกอบ​ทาง code: สี​ฟ้า to command object, สี​ส้ม to domain event record, สี​เหลือง to aggregate ที่​คุม invariant, สี​ม่วง to policy/event handler และ​สีชมพู to infrastructure client ที่​คุย​กับ​ระบบ​ภายนอก — นี่​คือ​เหตุผล​ที่ EventStorming ระดับ Software Design เชื่อม​ตรง​ไป​สู่​การ​ออกแบบ aggregate และ bounded context ได้​อย่าง​เป็น​ธรรมชาติ

EventStorming มัก​ถูก​เทียบ​หรือ​ใช้​คู่​กับ​เทคนิค​อื่น​ใน​กล่อง​เครื่องมือ​ของ DDD:

  • Domain Storytelling เน้น​เล่า​เรื่อง​ผ่าน actor และ work object เป็น​ภาพ pictographic ที​ละ​ประโยค เหมาะ​กับ​กลุ่ม​เล็ก​ที่​ต้องการ​ความ​ละเอียด​ของ “ใคร​ทำ​อะไร​กับ​อะไร” ส่วน EventStorming เน้น​เห็น​ภาพ​รวม​ของ timeline เหตุการณ์​จำนวน​มาก​พร้อม​กัน เหมาะ​กับ​การ​หา​ขอบเขต​และ pain point ใน​กลุ่ม​ใหญ่ ทั้ง​สอง​เทคนิค​เสริม​กัน​ได้ — เริ่ม​ด้วย EventStorming เพื่อ​หา​ภาพ​กว้าง แล้ว​ใช้ Domain Storytelling เจาะ​กระบวนการ​ที่​ซับซ้อน​เฉพาะ​จุด
  • Ubiquitous Language คือ​ผลพลอยได้​โดยตรง​ของ EventStorming เพราะ​คำ​ที่​เขียน​บน sticky note ทุก​ใบ​ต้อง​ผ่าน​การ​ต่อรอง​และ​ยอมรับ​ร่วม​กัน​ของ​ผู้​เข้า​ร่วม​ทุก​ฝ่าย​แบบ real-time
  • Bounded Context มัก​ถูก​ค้น​พบ​จาก​รอย​ต่อ​ของ timeline ใน Big Picture EventStorming เช่น จุด​ที่​คำ​ว่า “Order” มี​ความหมาย​ต่าง​กัน​ระหว่าง​ทีม Sales กับ​ทีม Fulfillment
  • รูปแบบ Domain Events (ใน​เชิง​สถาปัตยกรรม​ซอฟต์แวร์) คือ​ปลายทาง​ที่ sticky note สี​ส้ม​แปลง​ร่าง​ไป​เป็น เมื่อ workshop ลง​ถึง​ระดับ Software Design
  • Alberto Brandolini เน้น​ย้ำ​ว่า EventStorming เป็น “การ​เรียนรู้​ร่วม​กัน​อย่าง​จงใจ” (deliberate collective learning) ไม่ใช่​แค่​เทคนิค​วาด​ไดอะแกรม จุด​แข็ง​ของ​มัน​คือ​ความเร็ว​ใน​การ​เปิดเผย​ปัญหา​ที่​ซ่อน​อยู่ ซึ่ง​ช่วย​ฟื้น​ความ​นิยม​ของ​แนวคิด DDD และ​การ model ร่วม​กัน (collaborative modeling) ใน​วง​กว้าง​ช่วง​หลัง​ปี 2013