Chain of Responsibility Pattern #

Dalam pengembangan perangkat lunak, terutama ketika membangun sistem yang kompleks, kita sering menghadapi situasi di mana sebuah permintaan harus diproses oleh satu dari beberapa objek. Alih-alih memutuskan secara langsung siapa yang akan menangani permintaan tersebut, kita dapat menggunakan Chain of Responsibility Pattern untuk mengalirkan permintaan melalui rangkaian objek sampai ada yang mampu menanganinya.

Chain of Responsibility termasuk dalam kategori Behavioral Pattern, yang berfokus pada cara objek berinteraksi dan bertanggung jawab atas perilaku tertentu.

Apa itu Chain of Responsibility? #

Chain of Responsibility (CoR) adalah sebuah pola desain di mana sebuah permintaan dikirim melalui sebuah rantai objek penerima (handler) hingga salah satu handler mampu menangani permintaan tersebut. Setiap handler memiliki referensi ke handler berikutnya dalam rantai. Jika handler saat ini tidak dapat menangani permintaan, permintaan diteruskan ke handler berikutnya.

Konsep utamanya:

  • Ada rangkaian objek (handlers) yang dapat memproses permintaan.
  • Setiap objek memiliki kesempatan untuk menangani permintaan atau meneruskan ke objek berikutnya.
  • Pola ini mengurangi ketergantungan pengirim terhadap penerima tertentu.

Tujuan dari Pattern #

Tujuan utama penggunaan Chain of Responsibility Pattern:

  1. Mendelegasikan tanggung jawab secara dinamis di antara beberapa objek.
  2. Memisahkan pengirim dan penerima permintaan sehingga pengirim tidak perlu mengetahui siapa yang menangani.
  3. Membuat sistem lebih fleksibel dan mudah diperluas karena handler baru dapat ditambahkan tanpa mengubah kode pengirim.

Kapan Cocok Digunakan? #

Pola ini cocok digunakan ketika:

  • Ada beberapa objek yang mungkin menangani permintaan, tetapi tidak diketahui secara statis objek mana yang akan menangani.
  • Anda ingin mengurangi ketergantungan langsung antara pengirim dan penerima permintaan.
  • Anda ingin menambahkan atau mengubah handler secara mudah tanpa memodifikasi kode klien.

Contoh situasi:

  • Sistem logging dengan beberapa level (INFO, DEBUG, ERROR).
  • Validasi form dengan beberapa validator.
  • Proses permintaan customer service melalui beberapa level approval.

Contoh Implementasi (Golang) #

Berikut contoh sederhana Chain of Responsibility untuk menangani request logging:

package main

import "fmt"

// Handler interface
type Handler interface {
	SetNext(handler Handler)
	Handle(request string)
}

// BaseHandler struct
type BaseHandler struct {
	next Handler
}

func (b *BaseHandler) SetNext(handler Handler) {
	b.next = handler
}

func (b *BaseHandler) Handle(request string) {
	if b.next != nil {
		b.next.Handle(request)
	}
}

// Concrete Handlers

// InfoHandler handles "INFO" requests
type InfoHandler struct {
	BaseHandler
}

func (h *InfoHandler) Handle(request string) {
	if request == "INFO" {
		fmt.Println("InfoHandler menangani:", request)
	} else {
		h.BaseHandler.Handle(request)
	}
}

// ErrorHandler handles "ERROR" requests
type ErrorHandler struct {
	BaseHandler
}

func (h *ErrorHandler) Handle(request string) {
	if request == "ERROR" {
		fmt.Println("ErrorHandler menangani:", request)
	} else {
		h.BaseHandler.Handle(request)
	}
}

func main() {
	infoHandler := &InfoHandler{}
	errorHandler := &ErrorHandler{}

	infoHandler.SetNext(errorHandler)

	requests := []string{"INFO", "ERROR", "DEBUG"}

	for _, req := range requests {
		infoHandler.Handle(req)
	}
}

Output:

InfoHandler menangani: INFO
ErrorHandler menangani: ERROR

Permintaan “DEBUG” tidak ditangani karena tidak ada handler untuk itu.


Best Practices #

  1. Gunakan Handler Abstrak: Buat base handler yang memiliki implementasi default untuk SetNext dan Handle agar kode lebih bersih.
  2. Buat Handler Sederhana: Setiap handler sebaiknya hanya fokus pada satu tanggung jawab.
  3. Tambahkan Handler Baru Tanpa Merusak Rantai: Handler baru dapat ditambahkan di awal, akhir, atau tengah rantai tanpa mengubah handler yang sudah ada.
  4. Tangani Permintaan Tidak Dikenal: Pastikan ada handler default atau mekanisme fallback untuk permintaan yang tidak ditangani.
  5. Hindari Rantai yang Terlalu Panjang: Rantai yang terlalu panjang dapat mempersulit debugging dan mengurangi performa.

Penutup #

Dari pembahasan di atas, berikut apa yang bisa kita rangkum dari Chain of Responsibility Pattern:

  • Chain of Responsibility membantu mengurangi coupling antara pengirim dan penerima permintaan.
  • Bisa digabung dengan pola lain, misalnya Decorator untuk menambahkan perilaku tambahan saat permintaan diteruskan.
  • Sering digunakan di sistem event, logging, atau workflow approval.

Dengan menerapkan pola ini, sistem menjadi lebih modular, fleksibel, dan mudah diperluas ketika kebutuhan handler baru muncul.

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact