प्रेक्षक पैटर्न
सॉफ्टवेर डिज़ाइन और सॉफ्टवेयर इंजीनियरिंग में, ऑब्जर्वर पैटर्न एक सॉफ़्टवेयर डिज़ाइन पैटर्न है जिसमें ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में एक ऑब्जेक्ट (कंप्यूटर विज्ञान)#ऑब्जेक्ट, जिसे विषय कहा जाता है, अपने आश्रितों की एक सूची रखता है, जिन्हें पर्यवेक्षक कहा जाता है, और उन्हें स्वचालित रूप से सूचित करता है कोई भी घटना (कंप्यूटिंग), आमतौर पर उनकी किसी विधि (कंप्यूटर विज्ञान) को कॉल करके।
इसका उपयोग अक्सर इवेंट-संचालित प्रोग्रामिंग|इवेंट-संचालित सॉफ़्टवेयर में वितरित घटना से निपटना |इवेंट-हैंडलिंग सिस्टम को लागू करने के लिए किया जाता है। ऐसी प्रणालियों में, विषय को आमतौर पर घटनाओं की धारा या घटनाओं के धारा स्रोत का नाम दिया जाता है जबकि पर्यवेक्षकों को घटनाओं का सिंक कहा जाता है। धारा नामकरण एक भौतिक सेटअप की ओर संकेत करता है जिसमें पर्यवेक्षक भौतिक रूप से अलग हो जाते हैं और विषय/धारा स्रोत से उत्सर्जित घटनाओं पर उनका कोई नियंत्रण नहीं होता है। यह पैटर्न इस प्रकार किसी भी प्रक्रिया के लिए उपयुक्त है जिसके द्वारा डेटा कुछ इनपुट से आता है जो बूटिंग पर CPU के लिए उपलब्ध नहीं है, बल्कि इसके बजाय यादृच्छिक रूप से आता है (HTTP अनुरोध, GPIO डेटा, बाह्य उपकरणों से उपयोगकर्ता इनपुट, वितरित डेटाबेस और ब्लॉकचेन, आदि)।
अधिकांश आधुनिक प्रोग्रामिंग भाषाओं में पर्यवेक्षक-पैटर्न घटकों को लागू करने वाले अंतर्निहित इवेंट निर्माण शामिल होते हैं। हालांकि अनिवार्य नहीं है, अधिकांश पर्यवेक्षक कार्यान्वयन विषय की घटनाओं और कर्नेल द्वारा प्रदान किए गए अन्य समर्थन तंत्रों को सुनने के लिए डेमॉन (कंप्यूटिंग) का उपयोग करते हैं।
अवलोकन
ऑब्जर्वर डिज़ाइन पैटर्न 23 प्रसिद्ध डिज़ाइन पैटर्न के बीच सूचीबद्ध एक व्यवहारिक पैटर्न है गैंग ऑफ़ फोर डिज़ाइन पैटर्न जो लचीले और पुन: प्रयोज्य ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर को डिज़ाइन करने के लिए आवर्ती डिज़ाइन चुनौतियों का समाधान करते हैं, ऐसी ऑब्जेक्ट प्रदान करते हैं जिन्हें लागू करना, बदलना, परीक्षण करना और पुन: उपयोग करना आसान होता है।[1]
प्रेक्षक डिज़ाइन पैटर्न किन समस्याओं का समाधान कर सकता है?
पर्यवेक्षक पैटर्न निम्नलिखित समस्याओं का समाधान करता है:[2]
- वस्तुओं के बीच एक-से-अनेक निर्भरता को वस्तुओं को कसकर जोड़े बिना परिभाषित किया जाना चाहिए।
- जब एक वस्तु स्थिति बदलती है, तो आश्रित वस्तुओं की एक ओपन-एंडेड संख्या स्वचालित रूप से अपडेट की जानी चाहिए।
- एक वस्तु कई अन्य वस्तुओं को सूचित कर सकती है।
एक वस्तु (विषय) को परिभाषित करके वस्तुओं के बीच एक-से-अनेक निर्भरता को परिभाषित करना जो सीधे निर्भर वस्तुओं की स्थिति को अद्यतन करता है, अनम्य है क्योंकि यह विषय को विशेष निर्भर वस्तुओं से जोड़ता है। हालाँकि, यह प्रदर्शन के दृष्टिकोण से लागू हो सकता है या यदि ऑब्जेक्ट कार्यान्वयन कसकर युग्मित है (जैसे निम्न-स्तरीय कर्नेल संरचनाएं जो प्रति सेकंड हजारों बार निष्पादित होती हैं)। कसकर युग्मित वस्तुओं को कुछ परिदृश्यों में लागू करना मुश्किल हो सकता है और आसानी से पुन: उपयोग नहीं किया जाता है क्योंकि वे विभिन्न इंटरफेस के साथ कई वस्तुओं को संदर्भित करते हैं और उनसे अवगत होते हैं। अन्य परिदृश्यों में, कसकर युग्मित ऑब्जेक्ट एक बेहतर विकल्प हो सकते हैं क्योंकि कंपाइलर संकलन समय पर त्रुटियों का पता लगाने और सीपीयू अनुदेश स्तर पर कोड को अनुकूलित करने में सक्षम है।
ऑब्जर्वर डिज़ाइन पैटर्न किस समाधान का वर्णन करता है?
- परिभाषित करना
Subject
औरObserver
वस्तुएं. - जब कोई विषय स्थिति बदलता है, तो सभी पंजीकृत पर्यवेक्षकों को स्वचालित रूप से (और संभवतः अतुल्यकालिक रूप से) सूचित और अपडेट किया जाता है।
किसी विषय की एकमात्र ज़िम्मेदारी पर्यवेक्षकों की एक सूची बनाए रखना और उन्हें कॉल करके राज्य परिवर्तनों के बारे में सूचित करना है update()
कार्यवाही। पर्यवेक्षकों की ज़िम्मेदारी किसी विषय के साथ खुद को पंजीकृत और अपंजीकृत करना है (राज्य परिवर्तनों के बारे में सूचित होने के लिए) और अधिसूचित होने पर अपने राज्य को अद्यतन करना (अपने राज्य को विषय के राज्य के साथ सिंक्रनाइज़ करना)। यह विषय और पर्यवेक्षकों को शिथिल रूप से युग्मित बनाता है। विषय और पर्यवेक्षकों को एक दूसरे के बारे में कोई स्पष्ट ज्ञान नहीं है। पर्यवेक्षकों को रन टाइम पर स्वतंत्र रूप से जोड़ा और हटाया जा सकता है। इस अधिसूचना-पंजीकरण इंटरैक्शन को प्रकाशित-सदस्यता के रूप में भी जाना जाता है।
मजबूत बनाम कमजोर संदर्भ
पर्यवेक्षक पैटर्न स्मृति रिसाव का कारण बन सकता है, जिसे व्यपगत श्रोता समस्या के रूप में जाना जाता है, क्योंकि बुनियादी कार्यान्वयन में, इसे निपटान पैटर्न की तरह स्पष्ट पंजीकरण और स्पष्ट डीरजिस्ट्रेशन दोनों की आवश्यकता होती है, क्योंकि विषय पर्यवेक्षकों के लिए मजबूत संदर्भ रखता है, उन्हें जीवित रखता है। यदि विषय पर्यवेक्षकों के प्रति कमजोर संदर्भ रखता है तो इसे रोका जा सकता है।
युग्मन और विशिष्ट प्रकाशन-सदस्यता कार्यान्वयन
आमतौर पर, पर्यवेक्षक पैटर्न को लागू किया जाता है ताकि देखा जा रहा विषय उस वस्तु का हिस्सा हो जिसके लिए राज्य परिवर्तन देखे जा रहे हैं (और पर्यवेक्षकों को सूचित किया जाता है)। इस प्रकार के कार्यान्वयन को युग्मन (कंप्यूटर प्रोग्रामिंग) माना जाता है, जो पर्यवेक्षकों और विषय दोनों को एक-दूसरे के बारे में जागरूक होने और उनके आंतरिक भागों तक पहुंचने के लिए मजबूर करता है, जिससे scalability , गति, संदेश पुनर्प्राप्ति और रखरखाव (जिसे ईवेंट या ईवेंट भी कहा जाता है) के संभावित मुद्दे पैदा होते हैं। अधिसूचना हानि), सशर्त फैलाव में लचीलेपन की कमी और वांछित सुरक्षा उपायों में संभावित बाधा। प्रकाशन-सदस्यता पैटर्न के कुछ (मतदान (कंप्यूटर विज्ञान) | गैर-मतदान) कार्यान्वयन में, इसे पर्यवेक्षक और ऑब्जेक्ट के बीच एक अतिरिक्त चरण के रूप में एक समर्पित संदेश कतार सर्वर (और कभी-कभी एक अतिरिक्त संदेश हैंडलर ऑब्जेक्ट) बनाकर हल किया जाता है। अवलोकन किया जा रहा है, इस प्रकार घटकों को अलग किया जा रहा है। इन मामलों में, संदेश कतार सर्वर को पर्यवेक्षक पैटर्न के साथ पर्यवेक्षकों द्वारा एक्सेस किया जाता है, कुछ संदेशों की सदस्यता लेते हैं और केवल अपेक्षित संदेश के बारे में जानते हैं (या कुछ मामलों में नहीं जानते हैं), जबकि संदेश भेजने वाले के बारे में कुछ भी नहीं जानते हैं; प्रेषक को पर्यवेक्षकों के बारे में कुछ भी पता नहीं हो सकता है। प्रकाशित-सदस्यता पैटर्न के अन्य कार्यान्वयन, जो इच्छुक पार्टियों को अधिसूचना और संचार के समान प्रभाव प्राप्त करते हैं, पर्यवेक्षक पैटर्न का उपयोग नहीं करते हैं।[3][4] ओएस/2 और माइक्रोसॉफ़्ट विंडोज़ जैसे मल्टी-विंडो ऑपरेटिंग सिस्टम के शुरुआती कार्यान्वयन में, प्रकाशित-सदस्यता पैटर्न और इवेंट-संचालित सॉफ़्टवेयर विकास शब्द का उपयोग पर्यवेक्षक पैटर्न के पर्यायवाची के रूप में किया गया था।[5] पर्यवेक्षक पैटर्न, जैसा कि डिज़ाइन पैटर्न पुस्तक में वर्णित है, एक बहुत ही बुनियादी अवधारणा है और पर्यवेक्षकों को सूचित करने से पहले या बाद में देखे गए विषय द्वारा किए जाने वाले विशेष तर्क या देखे गए विषय में परिवर्तनों में रुचि को हटाने का समाधान नहीं करता है। यह पैटर्न परिवर्तन सूचनाओं को रिकॉर्ड करने या उनके प्राप्त होने की गारंटी देने से भी संबंधित नहीं है। इन चिंताओं को आम तौर पर संदेश-कतार प्रणाली में नियंत्रित किया जाता है, जिसमें पर्यवेक्षक पैटर्न केवल एक छोटा सा हिस्सा निभाता है।
संबंधित पैटर्न में प्रकाशित-सदस्यता, मध्यस्थ पैटर्न और सिंगलटन पैटर्न शामिल हैं।
अनयुग्मित
पर्यवेक्षक पैटर्न का उपयोग प्रकाशन-सदस्यता के अभाव में किया जा सकता है, जैसे कि जब मॉडल स्थिति अक्सर अद्यतन की जाती है। बार-बार अपडेट करने से दृश्य अनुत्तरदायी हो सकता है (उदाहरण के लिए, कई पेंटर के एल्गोरिदम कॉल को लागू करके); ऐसे पर्यवेक्षकों को इसके बजाय टाइमर का उपयोग करना चाहिए। परिवर्तन संदेश द्वारा अतिभारित होने के बजाय, पर्यवेक्षक एक नियमित अंतराल पर मॉडल की अनुमानित स्थिति का प्रतिनिधित्व करने के लिए दृश्य का कारण बनेगा। प्रेक्षक का यह मोड प्रगति पट्टी के लिए विशेष रूप से उपयोगी है, जिसमें अंतर्निहित ऑपरेशन की प्रगति बार-बार बदलती रहती है।
संरचना
यूएमएल वर्ग और अनुक्रम आरेख
इस एकीकृत मॉडलिंग भाषा वर्ग आरेख में, Subject
वर्ग निर्भर वस्तुओं की स्थिति को सीधे अद्यतन नहीं करता है। बजाय, Subject
यह आपकी जानकारी के लिए है Observer
इंटरफेस (update()
) राज्य को अद्यतन करने के लिए, जो बनाता है Subject
निर्भर वस्तुओं की स्थिति को अद्यतन करने के तरीके से स्वतंत्र। Observer1
ई> और Observer2
कक्षाएं कार्यान्वित करती हैं Observer
विषय की स्थिति के साथ उनकी स्थिति को सिंक्रनाइज़ करके इंटरफ़ेस।
एकीकृत मॉडलिंग भाषा अनुक्रम आरेख रनटाइम इंटरैक्शन दिखाता है: Observer1
ई> और Observer2
ऑब्जेक्ट कॉल करते हैं attach(this)
पर Subject1
खुद को पंजीकृत करने के लिए. यह मानते हुए कि स्थिति Subject1
परिवर्तन, Subject1
कॉल notify()
अपने आप पर. notify()
कॉल update()
पंजीकृत पर Observer1
और Observer2
ऑब्जेक्ट, जो परिवर्तित डेटा का अनुरोध करते हैं (getState()
) से Subject1
उनकी स्थिति को अद्यतन (सिंक्रनाइज़) करने के लिए।
यूएमएल वर्ग आरेख
उदाहरण
जबकि लाइब्रेरी कक्षाएं java.util.Observer
और java.util.Observable
मौजूद हैं, उन्हें जावा 9 में बहिष्कृत कर दिया गया है क्योंकि लागू किया गया मॉडल काफी सीमित था।
नीचे जावा (प्रोग्रामिंग भाषा) में लिखा गया एक उदाहरण है जो कीबोर्ड इनपुट लेता है और प्रत्येक इनपुट लाइन को एक इवेंट के रूप में संभालता है। जब एक स्ट्रिंग की आपूर्ति की जाती है System.in
, प्रक्रिया notifyObservers()
फिर घटना के घटित होने के बारे में सभी पर्यवेक्षकों को उनके अद्यतन तरीकों के आह्वान के रूप में सूचित करने के लिए बुलाया जाता है।
जावा
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
interface Observer {
void update(String event);
}
class EventSource {
List<Observer> observers = new ArrayList<>();
void notifyObservers(String event) {
observers.forEach(observer -> observer.update(event));
}
void addObserver(Observer observer) {
observers.add(observer);
}
void scanSystemIn() {
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
notifyObservers(line);
}
}
}
public class ObserverDemo {
public static void main(String[] args) {
System.out.println("Enter Text : ");
var eventSource = new EventSource();
eventSource.addObserver(event -> System.out.println("Received response: " + event));
eventSource.scanSystemIn();
}
}
सी++
यह C++11 कार्यान्वयन है. <सिंटैक्सहाइलाइट लैंग= सी++ >
- शामिल <कार्यात्मक>
- शामिल करें <iostream>
- शामिल <सूची>
कक्षा विषय; //ऑब्जर्वर में उपयोग के लिए अग्रेषित घोषणा
कक्षा पर्यवेक्षक { जनता:
स्पष्ट पर्यवेक्षक(विषय एवं विषय); आभासी ~पर्यवेक्षक(); ऑब्जर्वर(कॉन्स्ट ऑब्जर्वर&)=डिलीट; // तीन का नियम प्रेक्षक एवं ऑपरेटर=(स्थिरांक पर्यवेक्षक&) = हटाएं;
आभासी शून्य अद्यतन(विषय&s) स्थिरांक = 0;
निजी:
// डिस्ट्रक्टर में अलग करने के लिए विषय वस्तु का संदर्भ विषयवस्तु;
};
//विषय घटना निर्माण के लिए आधार वर्ग है कक्षा विषय { जनता:
RefObserver = std::reference_wrapper<const ऑब्जर्वर> का उपयोग करना; // सभी संलग्न पर्यवेक्षकों को सूचित करें शून्य सूचना() { (const auto& x: पर्यवेक्षकों) के लिए { x.get().update(*this); } } // एक पर्यवेक्षक जोड़ें शून्य संलग्न (स्थिरांक पर्यवेक्षक और पर्यवेक्षक) { पर्यवेक्षक.push_front(पर्यवेक्षक); } // एक पर्यवेक्षक को हटा दें शून्य पृथक्करण (पर्यवेक्षक एवं प्रेक्षक) { पर्यवेक्षकों.remove_if( [&पर्यवेक्षक ](स्थिरांक RefObserver& obj) { वापसी &obj.get()==&पर्यवेक्षक; }); }
निजी:
एसटीडी::सूची<RefObserver>पर्यवेक्षक;
};
पर्यवेक्षक::पर्यवेक्षक(विषय और विषय): विषय(विषय) {
विषय.संलग्न करें(*यह);
}
प्रेक्षक::~पर्यवेक्षक() {
विषय.डिटैच(*यह);
}
// उपयोग का उदाहरण
क्लास कंक्रीट ऑब्जर्वर: सार्वजनिक ऑब्जर्वर
{
जनता:
कंक्रीटऑब्जर्वर(विषय एवं विषय) : पर्यवेक्षक(विषय) {} // अधिसूचना पाएं शून्य अद्यतन(विषय&) स्थिरांक ओवरराइड { std::cout << एक सूचना मिली << std::endl; }
};
मुख्य प्रवेश बिंदु() {
विषय सीएस; कंक्रीटऑब्जर्वर co1(cs); कंक्रीटऑब्जर्वर CO2(cs); सीएस.सूचित करें();
} </सिंटैक्सहाइलाइट> प्रोग्राम आउटपुट इस प्रकार है
<सिंटैक्सहाइलाइट लैंग= सी++ > एक सूचना मिली एक सूचना मिली </सिंटैक्सहाइलाइट>
ग्रूवी
class EventSource {
private observers = []
private notifyObservers(String event) {
observers.each { it(event) }
}
void addObserver(observer) {
observers += observer
}
void scanSystemIn() {
var scanner = new Scanner(System.in)
while (scanner) {
var line = scanner.nextLine()
notifyObservers(line)
}
}
}
println 'Enter Text: '
var eventSource = new EventSource()
eventSource.addObserver { event ->
println "Received response: $event"
}
eventSource.scanSystemIn()
कोटलिन
import java.util.Scanner
typealias Observer = (event: String) -> Unit;
class EventSource {
private var observers = mutableListOf<Observer>()
private fun notifyObservers(event: String) {
observers.forEach { it(event) }
}
fun addObserver(observer: Observer) {
observers += observer
}
fun scanSystemIn() {
val scanner = Scanner(System.`in`)
while (scanner.hasNext()) {
val line = scanner.nextLine()
notifyObservers(line)
}
}
}
fun main(arg: List<String>) {
println("Enter Text: ")
val eventSource = EventSource()
eventSource.addObserver { event ->
println("Received response: $event")
}
eventSource.scanSystemIn()
}
डेल्फ़ी
uses
System.Generics.Collections, System.SysUtils;
type
IObserver = interface
['{0C8F4C5D-1898-4F24-91DA-63F1DD66A692}']
procedure Update(const AValue: string);
end;
type
TObserverManager = class
private
FObservers: TList<IObserver>;
public
constructor Create; overload;
destructor Destroy; override;
procedure NotifyObservers(const AValue: string);
procedure AddObserver(const AObserver: IObserver);
procedure UnregisterObsrver(const AObserver: IObserver);
end;
type
TListener = class(TInterfacedObject, IObserver)
private
FName: string;
public
constructor Create(const AName: string); reintroduce;
procedure Update(const AValue: string);
end;
procedure TObserverManager.AddObserver(const AObserver: IObserver);
begin
if not FObservers.Contains(AObserver)
then FObservers.Add(AObserver);
end;
begin
FreeAndNil(FObservers);
inherited;
end;
procedure TObserverManager.NotifyObservers(const AValue: string);
var
i: Integer;
begin
for i := 0 to FObservers.Count - 1 do
FObservers[i].Update(AValue);
end;
procedure TObserverManager.UnregisterObsrver(const AObserver: IObserver);
begin
if FObservers.Contains(AObserver)
then FObservers.Remove(AObserver);
end;
constructor TListener.Create(const AName: string);
begin
inherited Create;
FName := AName;
end;
procedure TListener.Update(const AValue: string);
begin
WriteLn(FName + ' listener received notification: ' + AValue);
end;
procedure TMyForm.ObserverExampleButtonClick(Sender: TObject);
var
LDoorNotify: TObserverManager;
LListenerHusband: IObserver;
LListenerWife: IObserver;
begin
LDoorNotify := TObserverManager.Create;
try
LListenerHusband := TListener.Create('Husband');
LDoorNotify.AddObserver(LListenerHusband);
LListenerWife := TListener.Create('Wife');
LDoorNotify.AddObserver(LListenerWife);
LDoorNotify.NotifyObservers('Someone is knocking on the door');
finally
FreeAndNil(LDoorNotify);
end;
end;
उत्पादन <पूर्व> श्रोता पति को सूचना मिली: कोई दरवाज़ा खटखटा रहा है श्रोता पत्नी को सूचना मिली: कोई दरवाज़ा खटखटा रहा है </पूर्व>
पायथन
Python_(प्रोग्रामिंग_भाषा) में एक समान उदाहरण:
class Observable:
def __init__(self):
self._observers = []
def register_observer(self, observer):
self._observers.append(observer)
def notify_observers(self, *args, **kwargs):
for obs in self._observers:
obs.notify(self, *args, **kwargs)
class Observer:
def __init__(self, observable):
observable.register_observer(self)
def notify(self, observable, *args, **kwargs):
print("Got", args, kwargs, "From", observable)
subject = Observable()
observer = Observer(subject)
subject.notify_observers("test", kw="python")
# prints: Got ('test',) {'kw': 'python'} From <__main__.Observable object at 0x0000019757826FD0>
सी#
public class Payload
{
public string Message { get; set; }
}
public class Subject : IObservable<Payload>
{
public ICollection<IObserver<Payload>> Observers { get; set; }
public Subject()
{
Observers = new List<IObserver<Payload>>();
}
public IDisposable Subscribe(IObserver<Payload> observer)
{
if (!Observers.Contains(observer))
{
Observers.Add(observer);
}
return new Unsubscriber(observer, Observers);
}
public void SendMessage(string message)
{
foreach (var observer in Observers)
{
observer.OnNext(new Payload { Message = message });
}
}
}
public class Unsubscriber : IDisposable
{
private IObserver<Payload> observer;
private IList<IObserver<Payload>> observers;
public Unsubscriber(
IObserver<Payload> observer,
IList<IObserver<Payload>> observers)
{
this.observer = observer;
this.observers = observers;
}
public void Dispose()
{
if (observer != null && observers.Contains(observer))
{
observers.Remove(observer);
}
}
}
public class Observer : IObserver<Payload>
{
public string Message { get; set; }
public void OnCompleted()
{
}
public void OnError(Exception error)
{
}
public void OnNext(Payload value)
{
Message = value.Message;
}
public IDisposable Register(Subject subject)
{
return subject.Subscribe(this);
}
}
जावास्क्रिप्ट
जावास्क्रिप्ट को बहिष्कृत कर दिया गया है Object.observe
फ़ंक्शन जो पर्यवेक्षक पैटर्न का अधिक सटीक कार्यान्वयन था।[7] यह प्रेक्षित वस्तु में परिवर्तन होने पर घटनाओं को सक्रिय कर देगा। पदावनत किये बिना Object.observe
फ़ंक्शन, पैटर्न को अधिक स्पष्ट कोड के साथ कार्यान्वित किया जा सकता है:[8]
let Subject = {
_state: 0,
_observers: [],
add: function(observer) {
this._observers.push(observer);
},
getState: function() {
return this._state;
},
setState: function(value) {
this._state = value;
for (let i = 0; i < this._observers.length; i++)
{
this._observers[i].signal(this);
}
}
};
let Observer = {
signal: function(subject) {
let currentValue = subject.getState();
console.log(currentValue);
}
}
Subject.add(Observer);
Subject.setState(10);
//Output in console.log - 10
यह भी देखें
- निहित आह्वान
- क्लाइंट-सर्वर मॉडल
- पर्यवेक्षक पैटर्न का उपयोग अक्सर इकाई-घटक-सिस्टम पैटर्न में किया जाता है
संदर्भ
- ↑ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 293ff. ISBN 0-201-63361-2.
- ↑ "ऑब्जर्वर डिज़ाइन पैटर्न - समस्या, समाधान और प्रयोज्यता". w3sDesign.com. Retrieved 2017-08-12.
- ↑ Comparison between different observer pattern implementations Moshe Bindler, 2015 (Github)
- ↑ Differences between pub/sub and observer pattern The Observer Pattern by Adi Osmani (Safari books online)
- ↑ The Windows Programming Experience Charles Petzold, Nov 10, 1992, PC Magazine (Google Books)
- ↑ "ऑब्जर्वर डिज़ाइन पैटर्न - संरचना और सहयोग". w3sDesign.com. Retrieved 2017-08-12.
- ↑ "jQuery - Listening for variable changes in JavaScript".
- ↑ "Jquery - Listening for variable changes in JavaScript".
बाहरी संबंध
- Observer implementations in various languages at Wikibooks