हमें ऑब्जर्वर और ऑब्जर्वेबल का उपयोग कब करना चाहिए?


200

एक साक्षात्कारकर्ता ने मुझसे पूछा:

क्या है Observerऔर Observableऔर जब हम उन्हें इस्तेमाल करना चाहिए?

मुझे इन शर्तों के बारे में पता नहीं था, इसलिए जब मैं घर वापस आया और Googling के बारे में शुरू किया Observerऔर Observable, मुझे विभिन्न संसाधनों से कुछ बिंदु मिले:

1) Observableएक वर्ग है और Observerएक इंटरफ़ेस है।

2) Observableवर्ग Observerएस की एक सूची रखता है ।

3) जब कोई Observableवस्तु अद्यतन की जाती है, तो यह सूचित करने के लिए update()इसके प्रत्येक की विधि को आमंत्रित करता Observerहै, इसे बदल दिया जाता है।

मुझे यह उदाहरण मिला:

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!");
    }
}

लेकिन मुझे समझ में नहीं क्यों हम क्या ज़रूरत है Observerऔर Observable? setChanged()और notifyObservers(message)तरीके क्या हैं ?


लिंक काम नहीं कर रहा है। @Androider क्या आप अद्यतन लिंक प्रदान कर सकते हैं?
prateek

यदि आप जावा 6 या इसके बाद के संस्करण का उपयोग कर रहे हैं, तो इस dzone.com/articles/java-ee6-events-lightweight
Ramiz Uddin

1
मैं डिजाइन पैटर्न की अच्छी समझ पाने के लिए इस पुस्तक को पढ़ने का सुझाव दूंगा । यह मूर्खतापूर्ण के रूप में आता है, लेकिन यह एक उत्कृष्ट शिक्षण उपकरण है।
काउंटऑफमोंटक्रिस्टो

1
हर कोई कृपया ध्यान दें कि; पर्यवेक्षक /
प्रेक्षण

जवाबों:


265

आपके पास एक छात्र और एक संदेश बोर्ड का एक ठोस उदाहरण है। जब कोई नया संदेश MessageBoard पर पोस्ट किया जाता है, तो पर्यवेक्षक उस सूची में खुद को जोड़कर पंजीकृत करना चाहते हैं, जिसे अधिसूचित किया जाना है। जब संदेश संदेश बोर्ड में एक संदेश जोड़ा जाता है, तो यह पर्यवेक्षकों की अपनी सूची पर प्रसारित होता है और उन्हें सूचित करता है कि यह घटना हुई थी।

ट्विटर सोचो। जब आप कहते हैं कि आप किसी का अनुसरण करना चाहते हैं, तो ट्विटर आपको उनकी अनुयायी सूची में जोड़ता है। जब उन्होंने एक नया ट्वीट भेजा, तो आप इसे अपने इनपुट में देखें। उस स्थिति में, आपका ट्विटर अकाउंट ऑब्जर्वर है और जिस व्यक्ति का आप अनुसरण कर रहे हैं वह ऑब्जर्वेबल है।

सादृश्य परिपूर्ण नहीं हो सकता है, क्योंकि ट्विटर पर मध्यस्थ होने की अधिक संभावना है। लेकिन यह बिंदु को दर्शाता है।


57

बहुत ही सरल शब्दों में (क्योंकि अन्य उत्तर आपको वैसे भी सभी आधिकारिक डिज़ाइन पैटर्न का उल्लेख कर रहे हैं, इसलिए आगे के विवरणों के लिए उन्हें देखें):

यदि आप एक ऐसा वर्ग रखना चाहते हैं जिस पर आपके कार्यक्रम के पारिस्थितिक तंत्र में अन्य वर्गों द्वारा नजर रखी जाती है, तो आप कहते हैं कि आप चाहते हैं कि कक्षा अवलोकन योग्य हो। यानी इसके राज्य में कुछ बदलाव हो सकते हैं जिन्हें आप बाकी कार्यक्रम में प्रसारित करना चाहते हैं।

अब, ऐसा करने के लिए हमें किसी प्रकार की विधि को कॉल करना होगा। हम नहीं चाहते हैं कि ऑब्जर्वेबल क्लास को उन कक्षाओं के साथ कसकर जोड़ा जाए जो इसे देखने में रुचि रखते हैं। यह परवाह नहीं करता कि यह कब तक है क्योंकि यह कुछ मानदंडों को पूरा करता है। (कल्पना करें कि यह एक रेडियो स्टेशन है, यह परवाह नहीं करता कि कौन सुन रहा है जब तक कि उनकी आवृत्ति पर एक एफएम रेडियो है)। यह प्राप्त करने के लिए कि हम एक इंटरफ़ेस का उपयोग करते हैं, प्रेक्षक के रूप में जाना जाता है।

इसलिए, ऑब्जर्वेबल क्लास में ऑब्जर्वर की एक सूची होगी (यानी आपके पास जो ऑब्जर्वर इंटरफ़ेस के तरीके हैं उन्हें लागू करना होगा)। जब भी यह कुछ प्रसारित करना चाहता है, यह सिर्फ सभी पर्यवेक्षकों पर एक के बाद एक विधि कहता है।

पहेली को बंद करने के लिए आखिरी बात यह है कि ऑब्जर्वेबल वर्ग को कैसे पता चलेगा कि कौन रुचि रखता है? अतः ऑब्जर्वेबल वर्ग को अपनी रूचि को पंजीकृत करने के लिए कुछ तंत्र की पेशकश करनी चाहिए। एक विधि जैसे addObserver(Observer o)आंतरिक रूप से पर्यवेक्षक को पर्यवेक्षकों की सूची में जोड़ देता है, ताकि जब कुछ महत्वपूर्ण होता है, तो यह सूची से गुजरता है और सूची में प्रत्येक उदाहरण के ऑब्जर्वर इंटरफ़ेस की संबंधित अधिसूचना विधि को कॉल करता है।

हो सकता है कि साक्षात्कार में उन्होंने आपसे स्पष्ट रूप से java.util.Observerऔर java.util.Observableसामान्य अवधारणा के बारे में नहीं पूछा । अवधारणा एक डिजाइन पैटर्न है, जो जावा को जरूरत पड़ने पर इसे जल्दी से कार्यान्वित करने में आपकी सहायता के लिए सीधे बॉक्स से समर्थन प्रदान करने के लिए होता है। इसलिए मैं आपको सुझाव दूंगा कि आप वास्तविक तरीकों / कक्षाओं के बजाय अवधारणा को समझें (जो आप उनकी आवश्यकता होने पर देख सकते हैं)।

अपडेट करें

आपकी टिप्पणी के जवाब में, वास्तविक java.util.Observableवर्ग निम्नलिखित सुविधाएं प्रदान करता है:

  1. java.util.Observerउदाहरणों की एक सूची बनाए रखना । अधिसूचित होने में दिलचस्पी रखने वाले नए उदाहरणों को इसके माध्यम से जोड़ा जा सकता है addObserver(Observer o), और हटाया जा सकता है deleteObserver(Observer o)

  2. आंतरिक स्थिति बनाए रखना, यह निर्दिष्ट करना कि क्या पर्यवेक्षकों के लिए अंतिम अधिसूचना के बाद से वस्तु बदल गई है। यह उपयोगी है क्योंकि यह उस हिस्से को अलग करता है जहां आप कहते हैं कि वह Observableबदल गया है, उस हिस्से से जहां आप परिवर्तनों को सूचित करते हैं। (जैसे यह उपयोगी है यदि आपके पास कई परिवर्तन हो रहे हैं और आप केवल प्रत्येक छोटे कदम के बजाय प्रक्रिया के अंत में सूचित करना चाहते हैं)। इसके माध्यम से किया जाता है setChanged()। इसलिए आप इसे तभी कहते हैं जब आप कुछ बदल जाते हैं Observableऔर आप चाहते हैं कि बाकी Observersको अंततः इसके बारे में पता चले।

  3. सभी पर्यवेक्षकों को सूचित करते हुए कि विशिष्ट Observableने राज्य बदल दिया है। इसके माध्यम से किया जाता है notifyObservers()। यह जांचता है कि क्या setChanged()अधिसूचना के साथ आगे बढ़ने से पहले ऑब्जेक्ट वास्तव में बदल गया है (यानी कॉल किया गया था)। Objectयदि आप अधिसूचना के साथ कुछ अतिरिक्त जानकारी पास करना चाहते हैं, तो 2 संस्करण हैं, एक तर्क के साथ और एक तर्क के साथ। आंतरिक रूप से ऐसा होता है कि यह सिर्फ Observerउदाहरणों की सूची के माध्यम से पुनरावृत्ति करता है और update(Observable o, Object arg)उनमें से प्रत्येक के लिए विधि कहता है। यह बताता है कि Observerकौन सी ऑब्जर्वेबल ऑब्जेक्ट थी जो बदल गई (आप एक से अधिक अवलोकन कर सकते हैं), और Object argसंभावित रूप से कुछ अतिरिक्त जानकारी ले जाने के लिए (के माध्यम से पारित) notifyObservers()


37

परिभाषा

ऑब्जर्वर पैटर्न का उपयोग तब किया जाता है जब वस्तुओं के बीच कई संबंधों में से एक होता है जैसे कि यदि किसी वस्तु को संशोधित किया जाता है, तो उसके आश्रित वस्तुओं को स्वचालित रूप से अधिसूचित किया जाता है और सभी आश्रित वस्तुओं के लिए इसी तरह के परिवर्तन किए जाते हैं।

उदाहरण

  1. मान लीजिए, आपका स्थायी पता बदल गया है तो आपको पासपोर्ट प्राधिकरण और पैन कार्ड प्राधिकरण को सूचित करने की आवश्यकता है। तो यहाँ पासपोर्ट प्राधिकरण और पैन कार्ड प्राधिकरण पर्यवेक्षक हैं और आप एक विषय हैं।

  2. फेसबुक पर भी अगर आप किसी को सब्सक्राइब करते हैं तो जब भी नया अपडेट होगा तो आपको सूचित किया जाएगा।

इसका उपयोग कब करें:

  1. जब कोई वस्तु अपने राज्य को बदलती है, तो अन्य सभी आश्रितों को निरंतरता बनाए रखने के लिए अपने राज्य को स्वचालित रूप से बदलना होगा

  2. जब विषय के पास पर्यवेक्षकों की संख्या के बारे में नहीं पता है।

  3. जब एक वस्तु को अन्य वस्तुओं को सूचित करने में सक्षम होना चाहिए बिना यह जाने कि वस्तुएं कौन हैं।

चरण 1

सब्जेक्ट क्लास बनाएं।

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();
  }
}   

}

चरण 2

ऑब्जर्वर क्लास बनाएं।

Observer.java

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

चरण 3

ठोस पर्यवेक्षक कक्षाएं बनाएँ

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() ); 
}

}

चरण 4

विषय और ठोस पर्यवेक्षक वस्तुओं का उपयोग करें।

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);
 }

}

चरण 5

आउटपुट सत्यापित करें।

पहला राज्य परिवर्तन: 15

हेक्स स्ट्रिंग: एफ

अष्ट स्ट्रिंग: १al

बाइनरी स्ट्रिंग: 1111

दूसरा राज्य परिवर्तन: 10

हेक्स स्ट्रिंग: ए

अष्टक स्ट्रिंग: १२

बाइनरी स्ट्रिंग: 1010


अच्छी तरह से समझाया :)
roottraveller

3
मुझे लगता है कि "डिफिकेशन" एक टाइपो है। मुझे उम्मीद है कि यह एक टाइपो है।
जॉनजॉन

10

वे ऑब्जर्वर डिजाइन पैटर्न के हिस्से हैं । आमतौर पर एक या अधिक पर्यवेक्षकों को एक अवलोकन में परिवर्तन के बारे में सूचित किया जाता है । यह एक सूचना है कि "कुछ" हुआ, जहां आप एक प्रोग्रामर के रूप में परिभाषित कर सकते हैं कि "कुछ" का अर्थ क्या है।

इस पैटर्न का उपयोग करते समय, आप दोनों संस्थाओं को एक-दूसरे से अलग करते हैं - पर्यवेक्षक प्लग करने योग्य हो जाते हैं।


मैं सराहना करूँगा, यदि आप board.changeMessage("More Homework!");अपने उत्तर की व्याख्या जोड़ेंगे, तो मेरा मतलब है कि जब changeMessage("More Homework!");आह्वान किया जाएगा तो क्या होगा ।
रवि

9

ऑब्जर्वर में ऑब्जर्वर उर्फ ​​कॉलबैक पंजीकृत है।

इसका उपयोग उदाहरण के लिए उन घटनाओं के बारे में बताया जाता है जो किसी समय हुई थीं। यह व्यापक रूप से यूआई घटनाओं (बटन क्लिक, टेक्स्टफिल्ड चेंज) जैसे प्रेषण कार्यों के लिए स्विंग, अजाक्स, जीडब्ल्यूटी में उपयोग किया जाता है।

स्विंग में आपको GXXT में AddXXXListener (Listener l) जैसी विधियाँ मिलती हैं, आपके पास (Async) कॉलबैक हैं।

जैसा कि पर्यवेक्षकों की सूची गतिशील है, पर्यवेक्षक रनटाइम के दौरान पंजीकरण और अपंजीकृत कर सकते हैं। यह भी एक अच्छा तरीका है कि पर्यवेक्षकों से अवलोकनीय है, क्योंकि इंटरफेस का उपयोग किया जाता है।


9

यदि साक्षात्कारकर्ता ऑब्जर्वर वर्गों और इंटरफेस का उपयोग किए बिना ऑब्जर्वर डिजाइन पैटर्न को लागू करने के लिए कहता है , तो आप निम्नलिखित सरल उदाहरण का उपयोग कर सकते हैं!

MyObserver प्रेक्षक इंटरफ़ेस के रूप में

interface MyObserver {

    void update(MyObservable o, Object arg);
}

ओब्जर्वेबल क्लास के रूप में MyObservable

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;
    }

    // ...
}

MyObserver और 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);
  }

}

5

"मैंने यह पता लगाने की कोशिश की, कि वास्तव में हमें ऑब्जर्वर और ऑब्जर्वेबल की आवश्यकता क्यों है"

जैसा कि पिछले उत्तर पहले ही कह चुके हैं, वे एक पर्यवेक्षक की स्वचालित सूचनाएं प्राप्त करने के लिए एक पर्यवेक्षक की सदस्यता लेने का साधन प्रदान करते हैं।

एक उदाहरण एप्लिकेशन जहां यह उपयोगी हो सकता है डेटा बाइंडिंग में है , मान लीजिए कि आपके पास कुछ UI हैं जो कुछ डेटा को संपादित करते हैं, और आप चाहते हैं कि UI अपडेट होने पर डेटा अपडेट हो जाए, तो आप अपने डेटा को देखने योग्य बना सकते हैं, और अपने UI घटकों की सदस्यता ले सकते हैं आँकड़े

नॉकआउट। जेवी एक एमवीवीएम जावास्क्रिप्ट फ्रेमवर्क है जिसमें एक शानदार शुरुआत ट्यूटोरियल है, जो कि वास्तव में ट्यूटोरियल के माध्यम से जाने की सलाह देते हैं। http://learn.knockoutjs.com/

मुझे यह लेख विजुअल स्टूडियो 2008 स्टार्ट पेज में भी मिला ( ऑब्जर्वर पैटर्न मॉडल व्यू कंट्रोलर (MVC) के विकास की नींव है ) http://visualstudiomagazine.com/articles/2013/08/14/the-observer-pattern-in -net.aspx


3

मैंने यहाँ पर्यवेक्षक पैटर्न का संक्षिप्त विवरण लिखा है: http://www.devcodenote.com/2015/04/design-patterns-observer-pattern.html

पोस्ट से एक स्निपेट:

ऑब्जर्वर पैटर्न: यह अनिवार्य रूप से वस्तुओं के बीच एक-से-कई संबंध स्थापित करता है और अन्योन्याश्रित वस्तुओं के बीच एक शिथिल युग्मित डिजाइन होता है।

पाठ्यपुस्तक की परिभाषा: ऑब्जर्वर पैटर्न वस्तुओं के बीच एक-से-कई निर्भरता को परिभाषित करता है ताकि जब कोई वस्तु राज्य बदलती है, तो उसके सभी आश्रितों को स्वचालित रूप से अधिसूचित और अद्यतन किया जाता है।

उदाहरण के लिए फ़ीड अधिसूचना सेवा पर विचार करें। प्रेक्षक मॉडल को समझने के लिए सदस्यता मॉडल सबसे अच्छे हैं।


0

ऑब्जर्वर पैटर्न का उपयोग तब किया जाता है जब वस्तुओं के बीच एक-से-कई संबंध होते हैं जैसे कि यदि किसी वस्तु को संशोधित किया जाता है, तो उसके आश्रित वस्तुओं को स्वचालित रूप से अधिसूचित किया जाना है।


0

Java9 के बाद से, दोनों इंटरफेस को हटा दिया गया है, जिसका अर्थ है कि आपको अब उनका उपयोग नहीं करना चाहिए। देखें ऑब्जर्वर जावा 9 में पदावनत है। हमें इसके बजाय क्या उपयोग करना चाहिए?

हालाँकि, आप अभी भी उनके बारे में साक्षात्कार प्रश्न प्राप्त कर सकते हैं ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.