Pola Pengamat di Jawa

1. Ikhtisar

Pada artikel ini, kami akan menjelaskan pola Observer dan melihat beberapa alternatif implementasi Java.

2. Apa Pola Pengamat itu?

Pengamat adalah pola desain perilaku. Ini menentukan komunikasi antara objek: yang dapat diamati dan pengamat . Sebuah diamati adalah obyek yang memberitahukan pengamat tentang perubahan di negaranya.

Misalnya, kantor berita dapat memberi tahu saluran saat menerima berita. Menerima berita inilah yang mengubah keadaan kantor berita, dan itu menyebabkan saluran diberitahukan.

Mari kita lihat bagaimana kita bisa menerapkannya sendiri.

Pertama, mari kita definisikan kelas NewsAgency :

public class NewsAgency { private String news; private List channels = new ArrayList(); public void addObserver(Channel channel) { this.channels.add(channel); } public void removeObserver(Channel channel) { this.channels.remove(channel); } public void setNews(String news) { this.news = news; for (Channel channel : this.channels) { channel.update(this.news); } } }

NewsAgency dapat diamati, dan ketika berita diperbarui, status NewsAgency berubah. Ketika perubahan terjadi, NewsAgency memberi tahu pengamat tentang fakta ini dengan memanggil metode update () mereka .

Untuk dapat melakukan itu, objek yang dapat diamati perlu menyimpan referensi ke pengamat , dan dalam kasus kami, itu adalah variabel saluran .

Sekarang mari kita lihat bagaimana pengamat , para Saluran kelas, bisa terlihat seperti. Ini harus memiliki metode update () yang dipanggil ketika status NewsAgency berubah:

public class NewsChannel implements Channel { private String news; @Override public void update(Object news) { this.setNews((String) news); } }

The Saluran antarmuka hanya memiliki satu metode:

public interface Channel { public void update(Object o); }

Sekarang, jika kita menambahkan instance NewsChannel ke daftar pengamat , dan mengubah status NewsAgency , instance NewsChannel akan diperbarui:

NewsAgency observable = new NewsAgency(); NewsChannel observer = new NewsChannel(); observable.addObserver(observer); observable.setNews("news"); assertEquals(observer.getNews(), "news");

Ada antarmuka Observer yang telah ditentukan di pustaka inti Java, yang membuat penerapan pola pengamat menjadi lebih sederhana. Mari kita lihat.

3. Implementasi Dengan Observer

The java.util.Observer antarmuka mendefinisikan update () metode, sehingga tidak perlu untuk mendefinisikan diri kita sendiri seperti yang kita lakukan pada bagian sebelumnya.

Mari kita lihat bagaimana kita bisa menggunakannya dalam implementasi kita:

public class ONewsChannel implements Observer { private String news; @Override public void update(Observable o, Object news) { this.setNews((String) news); } } 

Di sini, argumen kedua berasal dari Observable seperti yang akan kita lihat di bawah.

Untuk mendefinisikan observable , kita perlu memperluas kelas Observable Java :

public class ONewsAgency extends Observable { private String news; public void setNews(String news) { this.news = news; setChanged(); notifyObservers(news); } }

Perhatikan bahwa kita tidak perlu memanggil metode update () pengamat secara langsung. Kami hanya memanggil setChanged () dan notifyObservers () , dan kelas Observable melakukan sisanya untuk kami.

Juga, ini berisi daftar pengamat dan mengekspos metode untuk mempertahankan daftar itu - addObserver () dan deleteObserver ().

Untuk menguji hasilnya, kita hanya perlu menambahkan pengamat ke daftar ini dan menyetel berita:

ONewsAgency observable = new ONewsAgency(); ONewsChannel observer = new ONewsChannel(); observable.addObserver(observer); observable.setNews("news"); assertEquals(observer.getNews(), "news");

Antarmuka Observer tidak sempurna dan tidak digunakan lagi sejak Java 9. Salah satu kekurangannya adalah Observable bukanlah antarmuka melainkan kelas, itulah mengapa subclass tidak dapat digunakan sebagai observable.

Juga, pengembang dapat mengganti beberapa metode sinkron Observable dan mengganggu keamanan thread mereka.

Mari kita lihat antarmuka ProperyChangeListener , yang disarankan daripada menggunakan Observer .

4. Implementasi Dengan PropertyChangeListener

Dalam implementasi ini, sebuah observable harus menyimpan referensi ke instance PropertyChangeSupport . Ini membantu untuk mengirim notifikasi ke pengamat ketika properti kelas diubah.

Mari kita definisikan yang dapat diamati:

public class PCLNewsAgency { private String news; private PropertyChangeSupport support; public PCLNewsAgency() { support = new PropertyChangeSupport(this); } public void addPropertyChangeListener(PropertyChangeListener pcl) { support.addPropertyChangeListener(pcl); } public void removePropertyChangeListener(PropertyChangeListener pcl) { support.removePropertyChangeListener(pcl); } public void setNews(String value) { support.firePropertyChange("news", this.news, value); this.news = value; } }

Dengan menggunakan dukungan ini , kita dapat menambah dan menghapus pengamat, dan memberi tahu mereka ketika status pengamatan berubah:

support.firePropertyChange("news", this.news, value);

Di sini, argumen pertama adalah nama properti yang diamati. Argumen kedua dan ketiga adalah nilai lama dan barunya yang sesuai.

Pengamat harus mengimplementasikan PropertyChangeListener :

public class PCLNewsChannel implements PropertyChangeListener { private String news; public void propertyChange(PropertyChangeEvent evt) { this.setNews((String) evt.getNewValue()); } }

Karena kelas PropertyChangeSupport yang melakukan pemasangan kabel untuk kami, kami dapat memulihkan nilai properti baru dari acara tersebut.

Mari kita uji implementasinya untuk memastikan bahwa itu juga berfungsi:

PCLNewsAgency observable = new PCLNewsAgency(); PCLNewsChannel observer = new PCLNewsChannel(); observable.addPropertyChangeListener(observer); observable.setNews("news"); assertEquals(observer.getNews(), "news");

5. Kesimpulan

Dalam artikel ini, kita telah memeriksa dua cara untuk mengimplementasikan pola desain Observer di Java, dengan pendekatan PropertyChangeListener yang lebih disukai.

Kode sumber artikel tersedia di GitHub.