Selama bidang Ilmu Komputer dan Pemrograman ada, pemrogram yang cerdik telah menemukan kesamaan yang berulang dalam masalah yang mereka coba selesaikan. Dengan menggunakan kesamaan ini, berbagai pola desain telah dikembangkan yang dapat mengatasi kendala spesifik yang mungkin dihadapi suatu masalah. Pola desain Observer adalah salah satu contohnya.

Apa Pola Desain Pengamat itu?

Pola desain pengamat terdiri dari dua komponen utama: subjek dan pengamat. Ini menggambarkan hubungan antara kedua komponen ini termasuk tindakan apa yang dapat diambil. Secara umum, subjek akan menunggu hingga suatu peristiwa terjadi atau kriteria tertentu tercapai, kemudian mereka akan memberitahukan kepada pengamat yang perlu mengetahui informasi tersebut (Refactoring Guru) (Packt). Di bawah ini adalah dua representasi kasar dari subjek dan pengamat yang akan saya gunakan nanti sebagai contoh.

Subjek

Subjek mempunyai dua tugas utama: menangani permintaan dari pengamat dan memberi tahu pengamat terkait ketika suatu peristiwa terjadi atau kriteria tertentu tercapai. Dua jenis permintaan yang ditanganinya dari pengamat adalah permintaan berlangganan dan berhenti berlangganan. Ketika subjek menerima permintaan berlangganan dari pengamat, ia menambahkan pengamat tersebut ke daftar pengamat berlangganan. Jika subjek menerima permintaan berhenti berlangganan dari pengamat, maka pengamat tersebut akan dihapus dari daftar (Refactoring Guru). Setelah peristiwa subjek terjadi atau kriterianya tercapai, ia akan memberi tahu semua pengamat yang berlangganan dalam daftarnya (Paket). Di bawah ini saya telah menulis beberapa kode JavaScript untuk subjek sederhana, menggunakan sumber online untuk mengingatkan diri saya tentang sintaks yang tepat untuk mendefinisikan kelas dalam JavaScript (Sekolah W3). Di bagian selanjutnya, saya memiliki cuplikan kode serupa untuk pengamat, yang mungkin berguna dalam memahami perilaku kode subjek.

class Subject {
    //The constructor sets up the object's data when initialized
    constructor(name) {
        this.name = name;
        this.observers = new Set();
    }

    //notify() informs all interested observers of the subject
    //when the event has occured
    notify() {
        this.observers.forEach((observer) => {
            console.log(`${this.name} is notifying ${observer.name}`);
            setTimeout(() => {
                observer.handleNotify(this);
              }, 0);
            
        })
    }

    //handleSubscribe() handles subscribe requests from observers
    handleSubscribe(observer) {
        this.observers.add(observer);
    }

    //handleSubscribe() handles unsubscribe requests from observers
    handleUnsubscribe(observer) {
        this.observers.delete(observer);
    }
}

Pengamat

Pengamat juga melakukan dua tugas utama: mengirimkan permintaan ke subjek dan menangani pemberitahuan dari subjek. Dua jenis permintaan yang dikirimkan pengamat ke subjek adalah permintaan berlangganan dan berhenti berlangganan, yang memberitahu subjek untuk menambahkan pengamat ke daftar langganannya atau menghapusnya dari daftar masing-masing (Refactoring Guru). Kemudian, saat pengamat menerima notifikasi dari subjek, ia menangani notifikasi tersebut dengan menyelesaikan suatu tindakan (Packt). Di bawah ini saya telah menulis beberapa kode JavaScript untuk pengamat sederhana, sekali lagi menggunakan referensi online untuk sintaksis (Sekolah W3). Cuplikan kode ini berfungsi bersama dengan cuplikan kode subjek di atas untuk menerapkan pola desain pengamat yang lengkap.

class Observer {
    //The constructor sets up the object's data when initialized
    constructor(name) {
        this.name = name;
    }

    //subscribe() lets a subject know that the observer is interested
    subscribe(subject) {
        subject.handleSubscribe(this);
        console.log(`I (${this.name}) have subscribed to ${subject.name}!`);
    }

    //unsubscribe() lets a subject know that the observer is no longer interested
    unsubscribe(subject) {
        subject.handleUnsubscribe(this);
        console.log(`I (${this.name}) have unsubscribed from ${subject.name}!`);
    }

    //handleNotify() handles what the Observer wants to do when notfied
    handleNotify(subject) {
        console.log(`I (${this.name}) have been notified by ${subject.name}!`);
    }
}

Subjek dan Pengamat Berinteraksi

Sekarang setelah kita mengetahui fungsi subjek dan pengamat, akan berguna jika kita melihat contoh interaksi keduanya. Di bawah ini adalah komik strip yang dibuat dengan gambar kasar saya yang membantu mengilustrasikan interaksi antara subjek dan pengamat.

Bagi Anda yang lebih menyukai kode, interaksi yang sama dijelaskan pada cuplikan kode di bawah ini. Saya telah mengomentari efek setiap baris di bawahnya.

const eyeball = new Observer('eyeball');
const star = new Subject('star');

star.notify();
//Nothing Happens (star has no subscribed observers)

eyeball.subscribe(star);
//eyeball will be added to star's list of subscribed observers

star.notify();
//star will notify eyeball, 
//since eyeball is on its list of subscribed observers

eyeball.unsubscribe(star);
//eyeball will be removed from star's list of subscribed observers

star.notify();
//Nothing Happens (star has no subscribed observers)

Mengapa Pola Desain Ini Relevan?

Pola desain ini relevan karena sangat sering muncul dalam pengembangan UI yang reaktif dan responsif (termasuk desain web). Hal ini karena UI yang reaktif dan responsif sering kali memerlukan tindakan yang dilakukan setelah peristiwa tertentu terjadi atau kriteria tertentu tercapai. Misalnya, jika pengembang web ingin laman web melakukan tindakan ketika ‹div› diklik, mereka mungkin menulis beberapa kode yang mirip dengan cuplikan di bawah. Fungsi addEventListener() membuat pendengar peristiwa (pengamat) yang melakukan tindakan tertentu ketika pengendali peristiwa (subjek) ‹div› memberi tahu bahwa klik (peristiwa tertentu) telah terjadi (Dofactory) (Paket).

document.querySelector('#someDiv').addEventListener(click, () => {/* Do Something */})

Contoh lain dari pola desain pengamat yang beraksi adalah useState hook di React. Hook useState membuat objek status (subjek) yang menunggu hingga nilainya berubah (peristiwa tertentu) untuk memberi tahu penyaji React bahwa status telah berubah, sehingga dapat merender ulang halaman (Fernández).

const [value, setValue] = useState('initial value');

Baik Anda menggunakan pola desain pengamat secara langsung atau menggunakan pustaka yang mengimplementasikannya atau tidak, pola desain tersebut sering muncul. Semoga artikel ini membantu pembaca mendapatkan pemahaman yang lebih baik tentang cara kerja pola desain dan kapan hal itu mungkin berguna bagi mereka.

Bibliografi

pabrik do. (nd). Jpengamat AvaScript. pabrik do. Diakses pada 31 Maret 2023, dari https://www.dofactory.com/javascript/design-patterns/observer

Fernández, G. (2012, 1 Desember). Reaksi kait dan pola “Pengamat”. Bahasa Inggris Biasa. Diakses pada 31 Maret 2023, dari https://plainenglish.io/blog/react-hooks-and-the-observer-pattern-1e4274f0e5f5

Paket. (nd). Pola pengamat. Paket. Diakses pada 31 Maret 2023, dari https://subscription.packtpub.com/book/web-development/9781783287314/1/ch01lvl1sec12/the-observer-pattern

Guru Pemfaktoran Ulang. (nd). Pengamat. Guru Pemfaktoran Ulang. Diakses pada 31 Maret 2023, dari https://refactoring.guru/design-patterns/observer

Sekolah W3. (nd). Kelas JavaScript. Sekolah W3. Diakses pada 31 Maret 2023, dari https://www.w3schools.com/js/js_classes.asp

Gambar dibuat oleh saya di MS Paint

Kode yang saya tulis dalam VS Code