1. Apa itu Pola Rantai Tanggung Jawab

Pola Rantai Tanggung Jawab adalah pola desain perilaku yang memisahkan pengirim dan penerima permintaan, memungkinkan beberapa objek untuk menangani permintaan. Setiap penerima berisi referensi ke penerima lain, dan jika tidak dapat menangani permintaan, meneruskan permintaan ke penerima berikutnya sampai permintaan ditangani atau mencapai akhir rantai.

2. Karakteristik dan Kelebihan Pola Rantai Tanggung Jawab

Karakteristik dan kelebihan dari Pola Rantai Tanggung Jawab adalah sebagai berikut:

  • Pemisahan pengirim dan penerima: Pengirim tidak perlu peduli tentang penerima mana yang menangani permintaan, juga tidak perlu mengetahui penangan khusus dalam rantai tersebut.
  • Fleksibilitas: Memungkinkan penambahan, penghapusan, atau pengubahan urutan penangan dalam rantai secara dinamis tanpa memodifikasi kode pengirim dan penerima.
  • Perluasan: Mudah untuk memperluas rantai tanggung jawab dengan menambahkan penangan khusus baru.
  • Prinsip Tanggung Jawab Tunggal: Setiap penangan khusus hanya perlu peduli tentang logika penanganannya sendiri.
  • Konfigurabilitas: Rantai penangan dapat dikonfigurasi sesuai kebutuhan, memungkinkan permintaan yang berbeda memiliki rantai penangan yang berbeda.

3. Contoh Aplikasi Praktis dari Pola Rantai Tanggung Jawab

Pola Rantai Tanggung Jawab memiliki banyak aplikasi praktis, seperti:

  • Penanganan permintaan dalam aplikasi web: Dapat digunakan untuk menangani berbagai jenis permintaan, seperti otentikasi identitas, logging, dan verifikasi izin.
  • Penanganan kesalahan: Dapat digunakan untuk menangani kesalahan, dengan setiap penangan bertanggung jawab untuk menangani jenis kesalahan tertentu dan meneruskan kesalahan ke penangan berikutnya sesuai kebutuhan.
  • Penanganan acara: Dapat digunakan untuk menangani berbagai jenis acara, seperti acara klik pengguna, acara permintaan jaringan, dan lain sebagainya.

4. Implementasi Pola Rantai Tanggung Jawab di Golang

4.1 Diagram Kelas UML

Pola Rantai Tanggung Jawab Golang

4.2 Contoh Pendahuluan

Pada diagram kelas UML di atas, kita telah mendefinisikan sebuah penangan abstrak (Handler) dan dua penangan konkret (ConcreteHandler1 dan ConcreteHandler2). Klien (Client) memulai permintaan dengan memanggil metode handleRequest dari penangan.

4.3 Langkah Implementasi 1: Mendefinisikan Antarmuka Penangan Abstrak

type Handler interface {
    HandleRequest(request Request) error
    SetNext(handler Handler)
}

type Request interface {
    Condition bool
}

Antarmuka penangan abstrak mendefinisikan metode HandleRequest untuk memproses permintaan dan metode SetNext untuk mengatur penangan berikutnya.

4.4 Langkah Implementasi 2: Mengimplementasikan Kelas Penangan Konkret

type ConcreteHandler1 struct {
    next Handler
}

func (h *ConcreteHandler1) HandleRequest(request Request) error {
    // Logika untuk menangani permintaan
    if request.Condition {
        // Kode untuk menangani permintaan
        return nil
    } else {
        if h.next != nil {
            return h.next.HandleRequest(request)
        }
        return errors.New("Penangan tidak ditemukan")
    }
}

func (h *ConcreteHandler1) SetNext(handler Handler) {
    h.next = handler
}

type ConcreteHandler2 struct {
    next Handler
}

func (h *ConcreteHandler2) HandleRequest(request Request) error {
    // Logika untuk menangani permintaan
    if request.Condition {
        // Kode untuk menangani permintaan
        return nil
    } else {
        if h.next != nil {
            return h.next.HandleRequest(request)
        }
        return errors.New("Penangan tidak ditemukan")
    }
}

func (h *ConcreteHandler2) SetNext(handler Handler) {
    h.next = handler
}

Kelas penangan konkret mengimplementasikan antarmuka penangan abstrak dan mengganti metode HandleRequest dan SetNext.

4.5 Langkah Implementasi 3: Membangun Rantai Tanggung Jawab

handler1 := &ConcreteHandler1{}
handler2 := &ConcreteHandler2{}

handler1.SetNext(handler2)

Dengan menginstansiasi penangan konkret dan mengatur penangan berikutnya, sebuah rantai tanggung jawab dibangun.

4.6 Langkah Implementasi 4: Kode Klien

func main() {
    handler := &ConcreteHandler1{}

    // Membangun rantai tanggung jawab
    handler.SetNext(&ConcreteHandler2{})

    // Mengirim permintaan
    handler.HandleRequest(Request{Condition: true})
}

Pada kode klien, sebuah penangan konkret diinstansiasi, penangan berikutnya diatur, dan kemudian metode HandleRequest dipanggil untuk mengirim permintaan.