Belajar Software Architecture and Design Patterns - GoF Behavioral Patterns
Episode 7 of 28

Belajar Software Architecture and Design Patterns - GoF Behavioral Patterns

GoF Behavioral: Strategy untuk pricing/discount, Observer via EventEmitter2 dan Laravel Events, Template Method, Command sebagai queue job, Chain of Responsibility via Pipeline Laravel — ditutup checkout engine dengan strategy diskon plus pipeline validasi di 3 stack

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

Pendahuluan

Kelompok Behavioral adalah yang paling hidup di aplikasi backend nyata: ia mengatur bagaimana objek berkomunikasi, membagi tanggung jawab alur, dan membuat perilaku bisa ditukar. Lima pattern hari ini menutup katalog GoF series ini — dan semuanya akan langsung terpakai dalam latihan checkout engine.

Pattern

Strategy

Keluarga algoritma yang saling dipertukarkan — kita sudah menyentuhnya di OCP (episode 3):

Laravel - strategy diskon via interface
interface DiscountStrategy {
    public function apply(int $subtotalCents): int;
}
 
final class PercentageDiscount implements DiscountStrategy {
    public function __construct(private int $percent) {}
    public function apply(int $subCents): int {
        return $subCents - intdiv($subCents * $this->percent, 100);
    }
}
final class FixedDiscount implements DiscountStrategy {
    public function __construct(private int $offCents) {}
    public function apply(int $subCents): int { return max(0, $subCents - $this->offCents); }
}

Observer

Satu event, banyak pendengar tanpa saling mengenal:

@Injectable()
export class OrderService {
  constructor(@InjectEventEmitter() private emitter: EventEmitter2) {}
  place(dto: CheckoutDto) {
    const order = this.checkout.place(dto);
    this.emitter.emit('order.placed', order); // penerbit tak peduli siapa mendengar
  }
}
// Listener terpisah:
@OnEvent('order.placed')
async sendReceipt(e: OrderPlaced) { await this.mailer.receipt(e.order); }

Template Method & Command & Chain of Responsibility

  • Template Method: kerangka algoritma di base class, langkah bervariasi diserahkan subclass — cocok saat alur tetap tapi detail berubah per tipe.
  • Command: permintaan dibungkus objek → bisa antri, ulang, audit. Inilah bentuk dari queue job (dispatch(new SendInvoiceJob($order)) di Laravel).
  • Chain of Responsibility: request melewati rantai handler; tiap handler putuskan lanjut/berhenti.
Laravel - Pipeline = chain idiomatic
$result = app(Pipeline::class)
    ->send($checkoutData)
    ->through([
        ValidateStock::class,
        ApplyPromo::class,
        CheckFraudScore::class,
    ])
    ->then(fn ($data) => $this->orders->create($data));

Real-World Implementasi

Peta pemakaian pattern behavioral di ketiga stack:

PatternNestJSFiberLaravel
Strategyservice interface pricingstrategy interface auth methodpolicy/strategy via interface
ObserverEventEmitter2channel pub/sub / callback registryEvents/Listeners
CommandCQRS command (ep.20)command struct + dispatcherQueue jobs
Chainguard/pipe berlapismiddleware chainPipeline

Praktik

Target outline: checkout engine dengan strategy diskon + pipeline validasi di 3 stack.

interface ValidationStep {
  validate(cart: Cart): Promise<void>; // throw jika gagal
}
 
@Injectable()
export class CheckoutEngine {
  private discounts = new Map<string, DiscountRule>();
  register(code: string, rule: DiscountRule) { this.discounts.set(code, rule); }
 
  async process(cart: Cart, steps: ValidationStep[]): Promise<Receipt> {
    for (const step of steps) await step.validate(cart); // chain
    let total = cart.subtotal();
    for (const [code] of cart.promos)
      total = this.discounts.get(code)!.apply(total);   // strategy
    return Receipt.from(total);
  }
}

Ujian akhir latihan: tambahkan aturan "diskon gratis ongkir jika subtotal di atas 500 ribu" — harus bisa dilakukan hanya dengan mendaftarkan strategy/rule baru tanpa menyentuh CheckoutEngine.

Penutup

Rangkuman episode ini:

  • Strategy menukar algoritma (diskon/auth/pricing); Observer memisahkan reaksi (events/listeners).
  • Template Method untuk kerangka tetap-detail variabel; Command membungkus aksi jadi antrian; Chain/Pipeline memproses berurutan.
  • Checkout engine membuktikan kombinasi pattern menghasilkan kode yang ekstensif-tanpa-modifikasi.

Katalog GoF tuntas! Episode 8 mulai FASE 3 dengan fondasi data modeling: DTO, Entity & Value Object — tiga jenis objek yang sering dicampuradukkan dan jadi sumber utama kode kotor. Sampai jumpa!