Kapan kita harus menggunakan Observer dan Observable?

200

Seorang pewawancara bertanya kepada saya:

Apa itu Observerdan Observabledan kapan kita harus menggunakannya?

Saya tidak mengetahui persyaratan ini, jadi ketika saya kembali ke rumah dan mulai mencari Google Observerdan Observable, saya menemukan beberapa poin dari sumber yang berbeda:

1) Observableadalah kelas dan Observerantarmuka.

2) ObservableKelas memelihara daftar Observers.

3) Ketika suatu Observableobjek diperbarui, ia memanggil update()metode masing-masing Observeruntuk memberitahukan itu, itu berubah.

Saya menemukan contoh ini:

import java.util.Observable;
import java.util.Observer;

class MessageBoard extends Observable
{
    public void changeMessage(String message) 
    {
        setChanged();
        notifyObservers(message);
    }
}

class Student implements Observer 
{
    @Override
    public void update(Observable o, Object arg) 
    {
        System.out.println("Message board changed: " + arg);
    }
}

public class MessageBoardTest 
{
    public static void main(String[] args) 
    {
        MessageBoard board = new MessageBoard();
        Student bob = new Student();
        Student joe = new Student();
        board.addObserver(bob);
        board.addObserver(joe);
        board.changeMessage("More Homework!");
    }
}

Tetapi saya tidak mengerti mengapa kita perlu Observerdan Observable? Untuk apa setChanged()dan notifyObservers(message)metode apa?

Ravi
sumber
Tautan tidak berfungsi. @Androider Bisakah Anda memberikan tautan yang diperbarui?
prateek
Jika Anda menggunakan Java 6 atau lebih tinggi, cobalah dzone.com/articles/java-ee6-events-lightweight
Ramiz Uddin
1
Saya sangat menyarankan membaca buku ini untuk mendapatkan pemahaman yang baik tentang pola desain. Itu terlihat konyol, tetapi ini adalah alat pembelajaran yang sangat baik.
countofmontecristo
1
Semua orang harap dicatat bahwa; Pengamat / Diamati tidak lagi digunakan di Jawa 9. Alternatif: stackoverflow.com/questions/46380073/…
eren130

Jawaban:

265

Anda memiliki contoh nyata tentang Siswa dan Papan Pesan. Siswa mendaftar dengan menambahkan sendiri ke daftar Pengamat yang ingin diberitahu ketika Pesan baru diposting ke MessageBoard. Ketika sebuah Pesan ditambahkan ke MessageBoard, ia mengulangi daftar Pengamatnya dan memberi tahu mereka bahwa peristiwa itu terjadi.

Pikirkan Twitter. Ketika Anda mengatakan ingin mengikuti seseorang, Twitter menambahkan Anda ke daftar pengikut mereka. Ketika mereka mengirim tweet baru, Anda melihatnya di input Anda. Dalam hal itu, akun Twitter Anda adalah Pengamat dan orang yang Anda ikuti adalah Observable.

Analogi ini mungkin tidak sempurna, karena Twitter lebih cenderung menjadi Mediator. Tapi itu menggambarkan intinya.

Duffymo
sumber
57

Dalam istilah yang sangat sederhana (karena jawaban lain merujuk Anda ke semua pola desain resmi, jadi lihatlah untuk detail lebih lanjut):

Jika Anda ingin memiliki kelas yang dipantau oleh kelas lain dalam ekosistem program Anda, Anda mengatakan bahwa Anda ingin kelas dapat diamati. Yaitu mungkin ada beberapa perubahan di negara bagian yang Anda ingin disiarkan ke seluruh program.

Sekarang, untuk melakukan ini kita harus memanggil semacam metode. Kami tidak ingin kelas Observable untuk dipasangkan dengan kelas yang tertarik untuk mengobservasinya. Tidak peduli siapa itu asalkan memenuhi kriteria tertentu. (Bayangkan itu adalah stasiun radio, tidak peduli siapa yang mendengarkan selama mereka memiliki radio FM yang disetel pada frekuensinya). Untuk mencapai itu kami menggunakan antarmuka, yang disebut sebagai Pengamat.

Oleh karena itu, kelas yang dapat diobservasi akan memiliki daftar Pengamat (yaitu contoh yang menerapkan metode antarmuka Pengamat yang mungkin Anda miliki). Setiap kali ia ingin menyiarkan sesuatu, ia hanya memanggil metode pada semua pengamat, satu demi satu.

Hal terakhir untuk menutup teka-teki adalah bagaimana kelas Observable tahu siapa yang tertarik? Jadi kelas Observable harus menawarkan beberapa mekanisme untuk memungkinkan Pengamat mendaftarkan minat mereka. Metode sepertiaddObserver(Observer o) internal menambahkan Observer ke daftar pengamat, sehingga ketika sesuatu yang penting terjadi, ia akan melewati daftar dan memanggil metode pemberitahuan masing-masing dari antarmuka Observer dari setiap instance dalam daftar.

Mungkin dalam wawancara mereka tidak bertanya secara eksplisit tentang java.util.Observerdanjava.util.Observable tetapi tentang konsep generik. Konsepnya adalah pola desain, yang terjadi pada Java untuk memberikan dukungan secara langsung di luar kotak untuk membantu Anda mengimplementasikannya dengan cepat saat Anda membutuhkannya. Jadi saya akan menyarankan agar Anda memahami konsep daripada metode / kelas yang sebenarnya (yang dapat Anda cari ketika Anda membutuhkannya).

MEMPERBARUI

Menanggapi komentar Anda, java.util.Observablekelas aktual menawarkan fasilitas berikut:

  1. Menyimpan daftar java.util.Observerinstance. Contoh baru yang tertarik untuk diberi tahu dapat ditambahkan melalui addObserver(Observer o), dan dihapus melalui deleteObserver(Observer o).

  2. Mempertahankan keadaan internal, menentukan apakah objek telah berubah sejak pemberitahuan terakhir kepada pengamat. Ini berguna karena memisahkan bagian di mana Anda mengatakan bahwa Observabletelah berubah, dari bagian di mana Anda memberi tahu perubahan. (Mis. Berguna jika Anda memiliki banyak perubahan yang terjadi dan Anda hanya ingin memberi tahu di akhir proses daripada di setiap langkah kecil). Ini dilakukan melalui setChanged(). Jadi Anda sebut saja ketika Anda mengubah sesuatu ke Observabledan Anda ingin sisanya Observersakhirnya tahu tentang itu.

  3. Memberitahu semua pengamat bahwa kondisi spesifik Observabletelah berubah. Ini dilakukan melalui notifyObservers(). Ini memeriksa apakah objek telah benar-benar berubah (yaitu panggilan setChanged()dibuat) sebelum melanjutkan dengan pemberitahuan. Ada 2 versi, satu tanpa argumen dan satu lagi dengan Objectargumen, jika Anda ingin memberikan beberapa informasi tambahan dengan notifikasi. Secara internal apa yang terjadi adalah bahwa ia hanya mengulangi daftar Observerinstance dan memanggil update(Observable o, Object arg)metode untuk masing-masing. Ini memberitahukan objek Observermana yang bisa diamati yang berubah (Anda bisa mengamati lebih dari satu), dan ekstra Object arguntuk berpotensi membawa beberapa informasi tambahan (melewati notifyObservers().

jbx
sumber
37

Definisi

Pola pengamat digunakan ketika ada satu ke banyak hubungan antara objek seperti jika satu objek diubah, objek dependennya akan diberitahukan secara otomatis dan perubahan yang sesuai dilakukan untuk semua objek dependen.

Contohnya

  1. Katakanlah, alamat permanen Anda diubah maka Anda perlu memberi tahu otoritas paspor dan otoritas kartu pan. Jadi di sini otoritas paspor dan otoritas kartu pan adalah pengamat dan Anda adalah subjek.

  2. Di Facebook juga, Jika Anda berlangganan seseorang maka setiap kali pembaruan baru terjadi maka Anda akan diberitahu.

Kapan menggunakannya:

  1. Ketika satu objek mengubah statusnya, maka semua objek tanggungan lainnya harus secara otomatis mengubah statusnya untuk mempertahankan konsistensi

  2. Ketika subjek tidak tahu tentang jumlah pengamat yang dimilikinya.

  3. Ketika suatu benda harus bisa memberi tahu benda lain tanpa mengetahui siapa benda itu.

Langkah 1

Buat kelas Subjek.

Subject.java

  import java.util.ArrayList;
  import java.util.List;

  public class Subject {

  private List<Observer> observers 
        = new ArrayList<Observer>();
  private int state;

  public int getState() {
    return state;
  }

 public void setState(int state) {
   this.state = state;
   notifyAllObservers();
 }

   public void attach(Observer observer){
     observers.add(observer);       
   }

  public void notifyAllObservers(){
    for (Observer observer : observers) {
     observer.update();
  }
}   

}

Langkah 2

Buat kelas Pengamat.

Observer.java

public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Langkah 3

Buat kelas pengamat yang konkret

BinaryObserver.java

public class BinaryObserver extends Observer{

  public BinaryObserver(Subject subject){
     this.subject = subject;
     this.subject.attach(this);
  }

  @Override
  public void update() {
     System.out.println( "Binary String: " 
     + Integer.toBinaryString( subject.getState() ) ); 
  }

}

OctalObserver.java

public class OctalObserver extends Observer{

   public OctalObserver(Subject subject){
     this.subject = subject;
    this.subject.attach(this);
 }

  @Override
  public void update() {
    System.out.println( "Octal String: " 
    + Integer.toOctalString( subject.getState() ) ); 
  }

}

HexaObserver.java

public class HexaObserver extends Observer{

  public HexaObserver(Subject subject){
    this.subject = subject;
    this.subject.attach(this);
 }

  @Override
  public void update() {
     System.out.println( "Hex String: " 
    + Integer.toHexString( subject.getState() ).toUpperCase() ); 
}

}

Langkah 4

Gunakan objek pengamat Subjek dan konkret.

ObserverPatternDemo.java

 public class ObserverPatternDemo {
    public static void main(String[] args) {
       Subject subject = new Subject();

       new HexaObserver(subject);
       new OctalObserver(subject);
       new BinaryObserver(subject);

       System.out.println("First state change: 15");    
       subject.setState(15);
       System.out.println("Second state change: 10");   
       subject.setState(10);
 }

}

Langkah 5

Verifikasi output.

Perubahan status pertama: 15

Hex String: F

String Oktal: 17

Binary String: 1111

Perubahan status kedua: 10

Hex String: A

String Oktal: 12

Binary String: 1010

Mubarak
sumber
menjelaskan dengan baik :)
roottraveller
3
Saya pikir "Defination" adalah kesalahan ketik. Saya harap ini salah ketik.
JohnJohn
10

Mereka adalah bagian dari pola desain Observer . Biasanya satu atau lebih obervers mendapatkan informasi tentang perubahan dalam satu yang dapat diamati . Ini adalah pemberitahuan bahwa "sesuatu" terjadi, di mana Anda sebagai seorang programmer dapat mendefinisikan apa arti "sesuatu".

Saat menggunakan pola ini, Anda memisahkan kedua entitas dari satu sama lain - pengamat menjadi pluggable.

Andy
sumber
Saya akan menghargai, jika Anda akan menambahkan penjelasan board.changeMessage("More Homework!");dalam jawaban Anda, maksud saya apa yang terjadi ketika changeMessage("More Homework!");dipanggil.
Ravi
9

Pengamat alias panggilan balik terdaftar di Observable.

Ini digunakan untuk memberi informasi misalnya tentang peristiwa yang terjadi di beberapa titik waktu. Ini banyak digunakan dalam Swing, Ajax, GWT untuk mengirim operasi pada misalnya acara UI (klik tombol, bidang teks berubah dll).

Di Swing Anda menemukan metode seperti addXXXListener (Listener l), di GWT Anda memiliki callback (Async).

Karena daftar pengamat bersifat dinamis, pengamat dapat mendaftar dan membatalkan pendaftaran saat runtime. Ini juga merupakan cara yang baik melakukan decouple yang dapat diamati dari pengamat, karena antarmuka digunakan.

Pawel Solarski
sumber
9

Jika pewawancara meminta untuk menerapkan pola desain Observer tanpa menggunakan kelas dan antarmuka Observer, Anda dapat menggunakan contoh sederhana berikut!

MyObserver sebagai antarmuka pengamat

interface MyObserver {

    void update(MyObservable o, Object arg);
}

MyObservable sebagai kelas yang Dapat Diobservasi

class MyObservable
{
    ArrayList<MyObserver> myObserverList = new ArrayList<MyObserver>();

    boolean changeFlag = false;

    public void notifyObservers(Object o)
    {
        if (hasChanged())
        {
            for(MyObserver mo : myObserverList) {
                mo.update(this, o);
            }
            clearChanged();
        }
    }


    public void addObserver(MyObserver o) {
        myObserverList.add(o);        
    }

    public void setChanged() {
        changeFlag = true;
    }

    public boolean hasChanged() {
        return changeFlag;
    }

    protected void clearChanged() {
        changeFlag = false;
    }

    // ...
}

Contoh Anda dengan MyObserver dan MyObservable!

class MessageBoard extends MyObservable {
  private String message;

  public String getMessage() {
    return message;
  }

  public void changeMessage(String message) {
    this.message = message;
    setChanged();
    notifyObservers(message);
  }

  public static void main(String[] args) {
    MessageBoard board = new MessageBoard();
    Student bob = new Student();
    Student joe = new Student();
    board.addObserver(bob);
    board.addObserver(joe);
    board.changeMessage("More Homework!");
  }
}

class Student implements MyObserver {

  @Override
  public void update(MyObservable o, Object arg) {
    System.out.println("Message board changed: " + arg);
  }

}
Habeeb Perwad
sumber
5

"Aku mencoba mencari tahu, mengapa sebenarnya kita membutuhkan Pengamat dan Terpantau"

Seperti jawaban sebelumnya telah dinyatakan, mereka menyediakan sarana untuk berlangganan pengamat untuk menerima pemberitahuan otomatis yang dapat diamati.

Salah satu contoh aplikasi di mana ini mungkin berguna adalah dalam pengikatan data , katakanlah Anda memiliki beberapa UI yang mengedit beberapa data, dan Anda ingin UI bereaksi ketika data diperbarui, Anda dapat membuat data Anda dapat diamati, dan berlangganan komponen UI Anda ke data

Knockout.js adalah kerangka kerja javascript MVVM yang memiliki tutorial memulai yang bagus, untuk melihat lebih banyak tindakan yang dapat diobservasi, saya sangat merekomendasikan melalui tutorial. http://learn.knockoutjs.com/

Saya juga menemukan artikel ini di halaman awal Visual Studio 2008 ( Pola Observer adalah dasar pengembangan Model View Controller (MVC) ) http://visualstudiomagazine.com/articles/2013/08/14/the-observer-pattern-in -net.aspx

Eduardo Wada
sumber
3

Saya telah menulis deskripsi singkat tentang pola pengamat di sini: http://www.devcodenote.com/2015/04/design-patterns-observer-pattern.html

Cuplikan dari pos:

Observer Pattern: Ini pada dasarnya membangun hubungan satu-ke-banyak antara objek dan memiliki desain yang digabungkan secara longgar antara objek yang saling tergantung.

Definisi TextBook: Pola Observer mendefinisikan ketergantungan satu-ke-banyak antara objek sehingga ketika satu objek berubah keadaan, semua tanggungannya diberitahu dan diperbarui secara otomatis.

Pertimbangkan layanan pemberitahuan umpan misalnya. Model berlangganan adalah yang terbaik untuk memahami pola pengamat.

Abhishek Jain
sumber
0

Pola pengamat digunakan ketika ada hubungan satu-ke-banyak antara objek seperti jika satu objek diubah, objek dependennya akan diberitahukan secara otomatis.

Swapnil Sharma
sumber