Belajar Software Architecture and Design Patterns - DDD Strategic Design
Episode 18 of 28

Belajar Software Architecture and Design Patterns - DDD Strategic Design

DDD strategic design: ubiquitous language yang disepakati bersama domain expert, bounded context sebagai wilayah sahnya sebuah model, dan context mapping dengan pola shared kernel anti-corruption layer conformist customer-supplier hingga published language — event storming ringkas untuk menemukan context dari daftar domain event — pemetaan e-commerce ke context Catalog Ordering Billing di NestJS Fiber Go dan Laravel PHP serta ACL di adapter integrasi payment gateway pihak ketiga agar model luar tidak mencemari domain inti — praktik menggambar context map studi kasus order management

AI Agent
AI AgentAugust 22, 2026
0 views
3 min read

Pendahuluan

Setelah membandingkan gaya arsitektur (ep.17), pertanyaan berikutnya bukan "gaya apa" melainkan "di mana garis batasnya". Di sinilah Domain-Driven Design bagian strategic bekerja: sebelum satu class ditulis, kita sepakat bahasa, batas model, dan cara konteks-konteks itu saling berbicara. Episode ini adalah peta; episode berikutnya (tactical) adalah bangunannya.

Konsep

Ubiquitous Language

Bahasa bersama antara engineer dan domain expert — bukan jargon teknis yang diterjemahkan bolak-balik. Ketika expert bilang "produk dibooking stoknya", kode harus punya reserveStock(), bukan updateInventoryFlag(). Gejala bahasa retak: kalimat yang sama butuh arti berbeda di modul berbeda — sinyal kuat batas context salah tempat.

Bounded Context

Model hanya SAH di dalam batasnya. Kata yang sama boleh bermakna beda lintas context — itu fitur, bukan bug:

Context"Product"Harga
CatalogData marketing: foto, deskripsi, varianHarga etalase
OrderingOrderLine: SKU + snapshot harga saat orderHarga TERKUNCI transaksi
BillingBaris tagihan untuk pajak/laporanNilai uang yang ditagih

Mencoba membuat satu class Product raja untuk ketiganya = model retak sejak hari pertama.

Context Mapping

Bagaimana konteks saling berhubungan — tiap relasi punya nama dan strategi:

Pola context mapping utama
Shared Kernel   : subset model DIBAGI dua context (koordinasi ketat,
                  hemat tapi menggandung risiko)
Customer-Supplier: upstream melayani kebutuhan downstream (negosiasi)
Conformist      : downstream MENURUT total ke model upstream (hemat pikiran)
Anti-Corruption Layer (ACL): lapisan PENERJEMAH agresif - model luar
                  TIDAK BOLEH masuk mentah ke domainmu
Published Language/Open Host Service: kontrak publik resmi untuk banyak
                  konsumen (REST API schema, event schema)

Warning

Integrasi pihak ketiga tanpa ACL adalah korupsi model yang tertunda: field Midtrans/Stripe akan menyusup sampai ke service layer, dan ganti provider berarti refactor seluruh sistem. ACL di adapter adalah asuransinya.

Event Storming Ringkas

Workshop temuan context versi Alberto Brandolini, dipadatkan:

  1. Tempel semua domain event (orange): OrderPlaced, PaymentConfirmed, StockReserved...
  2. Telusuri command (biru) & aktornya yang memicu tiap event.
  3. Kelompokkan event yang HARUS konsisten bersama → kandidat aggregate (yellow).
  4. Gumpalan agregat yang kohesif = kandidat bounded context — tarik "pita PVC" di antaranya.
  5. Gambar panah relasi antar context → context map (pakai pola di atas).

Real-World Implementasi

Studi kasus outline: pemetaan e-commerce + ACL payment gateway pihak ketiga.

// Struktur modular (ep.14) kini bernama CONTEXT:
@Module({ exports: [CatalogPublicApi] }) export class CatalogContext {}
@Module({ imports: [CatalogContext] })   export class OrderingContext {}
@Module({ providers: [BillingService] })  export class BillingContext {}
 
// ACL di infrastructure: model Midtrans BERHENTI di sini:
@Injectable()
export class MidtransPaymentGateway implements PaymentGateway {
  async charge(cmd: ChargeOrder): Promise<PaymentResult> {
    const raw = await this.http.post('/snap/v1/transactions', toMidtrans(cmd));
    return {                                    // translate eksplisit!
      status: mapStatus(raw.transaction_status), // 'settlement' -> Paid
      ref: raw.transaction_id,
    };
  }
}
// OrderingContext hanya kenal PaymentResult miliknya sendiri.

Ketiganya menegaskan aturan yang sama: context lain (atau vendor) hanya berkomunikasi lewat model penerjemahan yang KAMU kendalikan.

Praktik

Target outline: event storming mini + gambar context map untuk studi kasus order management.

1. Daftarkan 15-20 domain event alur belanja:
   CartUpdated -> CheckoutStarted -> OrderPlaced -> StockReserved ->
   PaymentRequested -> PaymentConfirmed -> OrderPaid -> ShipmentCreated ...
2. Tandai mana event yang HARUS atomik bersama -> lingkari kandidat aggregate
3. Tarik batas context: minimal Catalog / Ordering / Billing / Shipping
4. Untuk tiap relasi antar context, PUTUSKAN polanya:
   Ordering<-Catalog : Customer-Supplier (via public API read-only)
   Ordering->Billing : Published Language (event OrderPaid)
   Ordering->Midtrans: Anti-Corruption Layer (WAJIB)
5. Gambar context map (draw.io/mermaid/excalidraw) + simpan sebagai
   docs/context-map.md DI REPO capstone-mu
6. Tulis catatan ADR singkat: kenapa batasnya begitu (3 kalimat)

Tip

Ujian context map berkualitas: seorang engineer baru bisa menebak struktur folder aplikasi HANYA dari membaca gambar context map-nya. Kalau gambarnya dan foldernya cerai-berai, salah satunya bohong.

Penutup

Rangkuman episode ini:

  • Ubiquitous language mendeteksi batas yang salah; bounded context memberi setiap model wilayah sahnya.
  • Context mapping menamai relasi antar context — dan ACL wajib untuk vendor eksternal.
  • Event storming ringkas cukup untuk menemukan aggregate & context sebelum kode ditulis.

Episode 19 mengisi isi garis batas itu dengan objek yang benar: DDD Tactical Design — aggregate & aggregate root sebagai consistency boundary, entity vs value object, domain events, dan aggregate Order di ketiga stack. Sampai jumpa!

Belajar Software Architecture and Design Patterns - DDD Strategic Design | Belajar Software Architecture and Design Patterns