Vấn đề là markPaid đang biết quá nhiều về hệ thống xung quanh: thêm một việc phải-làm-khi-thanh-toán là lại sửa nó.
Tách theo hướng Observer / publish-subscribe: markPaid chỉ cập nhật trạng thái rồi phát ra một sự kiện, các bên quan tâm tự đăng ký.
orderEvents.on('order.paid', sendReceiptMail)
orderEvents.on('order.paid', reserveStock)
orderEvents.on('order.paid', pushNotification)
async function markPaid(id: string) {
await orders.update(id, { status: 'paid' })
orderEvents.emit('order.paid', { id })
}Thêm hành vi mới = thêm một subscriber, không đụng vào logic đơn hàng.
Ba điểm phải trả lời được khi bị hỏi tiếp:
- Lỗi của subscriber. Một handler ném exception không được làm hỏng handler khác và không được làm rollback việc đã cập nhật trạng thái. Bọc từng handler.
- Trong process hay qua queue. Event emitter trong process mất sạch khi server restart giữa chừng. Việc quan trọng (gửi mail, trừ kho) nên đẩy qua message queue để có retry và ghi bền.
- Khó lần vết. Luồng trở nên gián tiếp, khó đọc bằng cách "nhảy vào định nghĩa". Đặt tên event theo nghiệp vụ và giữ danh sách subscriber ở một chỗ đăng ký tập trung.