1. Apa itu Pola Pengamat (Observer Pattern)

Pola Pengamat (Observer Pattern) adalah sebuah pola desain perilaku yang digunakan untuk membentuk ketergantungan satu-ke-banyak antara objek. Secara khusus, ketika sebuah objek (yang disebut sebagai subjek atau yang dapat diamati) berubah, semua ketergantungannya (yang disebut sebagai pengamat) akan diberitahu dan diperbarui secara otomatis. Pola ini memungkinkan ketergantungan longgar antara subjek dan pengamat, sehingga mencapai dekupling dan fleksibilitas antar objek.

2. Karakteristik dan Keuntungan dari Pola Pengamat (Observer Pattern)

Pola Pengamat (Observer Pattern) memiliki karakteristik dan keuntungan berikut:

  • Ketergantungan longgar antara subjek dan pengamat, di mana subjek tidak perlu mengetahui detail implementasi khusus dari pengamat.
  • Penambahan dan penghapusan pengamat secara dinamis, menjadikan sistem lebih fleksibel.
  • Mengikuti prinsip terbuka-tertutup antara subjek dan pengamat, memungkinkan perluasan dan kegunaan independen.
  • Dapat membentuk hubungan ketergantungan satu-ke-banyak, di mana subjek dapat memiliki beberapa pengamat.

3. Contoh Penerapan Praktis dari Pola Pengamat (Observer Pattern)

Pola Pengamat (Observer Pattern) memiliki banyak aplikasi praktis dalam kehidupan nyata, seperti:

  • Mekanisme penanganan acara dalam antarmuka GUI, seperti menangani tindakan saat tombol diklik.
  • Penyiaran kutipan pasar saham real-time.
  • Pemberitahuan aktivitas promosi di platform e-commerce.

4. Implementasi Pola Pengamat (Observer Pattern) di Golang

4.1 Diagram Kelas UML

Pola Pengamat di Golang

4.2 Pengantar Contoh

Dalam contoh ini, kami memiliki sebuah subjek (Subject) dan dua pengamat (ObserverA dan ObserverB). Subjek dapat mendaftar, menghapus pendaftaran, dan memberi tahu pengamat.

4.3 Langkah-langkah Implementasi

4.3.1 Membuat Interface Subjek dan Kelas Subjek Konkret

type Subject interface {
    RegisterObserver(observer Observer)
    RemoveObserver(observer Observer)
    NotifyObservers()
}

type ConcreteSubject struct {
    observers []Observer
}

// Mendaftarkan objek pengamat
func (subject *ConcreteSubject) RegisterObserver(observer Observer) {
    subject.observers = append(subject.observers, observer)
}

// Menghapus objek pengamat
func (subject *ConcreteSubject) RemoveObserver(observer Observer) {
    for i, obs := range subject.observers {
        if obs == observer {
            subject.observers = append(subject.observers[:i], subject.observers[i+1:]...)
            break
        }
    }
}

// Memicu pemberitahuan acara
func (subject *ConcreteSubject) NotifyObservers() {
    for _, observer := range subject.observers {
        observer.Update()
    }
}

4.3.2 Membuat Interface Pengamat dan Kelas Pengamat Konkret

type Observer interface {
    Update()
}

type ConcreteObserverA struct {}

func (observer *ConcreteObserverA) Update() {
    fmt.Println("Pengamat A diberitahu.")
}

type ConcreteObserverB struct {}

func (observer *ConcreteObserverB) Update() {
    fmt.Println("Pengamat B diberitahu.")
}

4.4 Demo Kode Contoh

func main() {
    subject := &ConcreteSubject{}
    observerA := &ConcreteObserverA{}
    observerB := &ConcreteObserverB{}

    subject.RegisterObserver(observerA)
    subject.RegisterObserver(observerB)

    subject.NotifyObservers()

    subject.RemoveObserver(observerA)

    subject.NotifyObservers()
}

Output:

Pengamat A diberitahu.
Pengamat B diberitahu.
Pengamat B diberitahu.

Kode contoh di atas menunjukkan implementasi spesifik dari pola pengamat. Subjek (ConcreteSubject) mendaftarkan dua pengamat (PengamatA dan PengamatB), dan kemudian memberitahu kedua pengamat ini. Setelah itu, pengamat A didaftarkan dari subjek dan pengamat B yang tersisa diberitahu lagi.