โ Kembali ke Design Pattern
โ๏ธ
Behavioral
Chain of Responsibility
Meneruskan request melalui rantai handler; setiap handler memutuskan apakah akan menanganinya atau meneruskannya.
Masalahnya
Beberapa objek mungkin bisa menangani sebuah request, tetapi kamu tidak tahu yang mana sebelumnya. Kamu ingin menghindari keterikatan pengirim dengan satu penerima tertentu.
Cara Kerja
- โบSetiap handler menyimpan referensi ke handler berikutnya dalam rantai
- โบHandler menangani request itu sendiri atau meneruskannya ke handler berikutnya
- โบPengirim tidak perlu tahu handler mana yang akan memproses request
- โบHandler bisa ditambah, dihapus, atau diurutkan ulang saat runtime
- โบRequest bisa saja tidak tertangani jika tidak ada handler yang memprosesnya; tentukan perilaku default
Kapan Digunakan
โLebih dari satu handler bisa memproses request (pipeline middleware)
โHandler yang dipakai harus ditentukan saat runtime
โPengecekan izin, rantai validasi, event bubbling
โPipeline logging, request interceptor
Contoh di Dunia Nyata
๐
iOS
UIResponder chain (touch events bubble up from subview to window), URLProtocol subclasses
๐ค
Android
OkHttp Interceptor chain, View.onTouchEvent propagation, Compose event handling
๐
Web
Express.js middleware (next()), Koa.js, DOM event bubbling, NestJS guards/interceptors
Contoh Kode
Swift
protocol RequestHandler: AnyObject {
var next: RequestHandler? { get set }
func handle(request: Int) -> String?
}
class LowHandler: RequestHandler {
var next: RequestHandler?
func handle(request: Int) -> String? {
guard request > 10 else { return "Low handled \(request)" }
return next?.handle(request: request)
}
}
class MediumHandler: RequestHandler {
var next: RequestHandler?
func handle(request: Int) -> String? {
guard request > 50 else { return "Medium handled \(request)" }
return next?.handle(request: request)
}
}
class HighHandler: RequestHandler {
var next: RequestHandler?
func handle(request: Int) -> String? { "High handled \(request)" }
}
let low = LowHandler(); let med = MediumHandler(); let high = HighHandler()
low.next = med; med.next = high
print(low.handle(request: 5)!) // "Low handled 5"
print(low.handle(request: 30)!) // "Medium handled 30"
print(low.handle(request: 99)!) // "High handled 99"