Design mode C + + DESCRIPTION----04. Observer (Observer) mode

Source: Internet
Author: User
Tags assert

I. Overview

The Observer model solves the problem of creating a one (Subject) dependency on multiple (Observer), and doing so when "one" changes, depending on the number of "one" can also be synchronized.

The sbuject corresponds to the notifying person, which provides the registration (Attach) and logoff (Detach) operations that depend on its observer observer, and provides operations (Notify) that synchronize all the observers that depend on it.

Observer is equivalent to an observer, it provides an update operation, noting that the Observer update operation here does not update itself when Observer changes the Subject target State, and the update operation is deferred until the Subject object emits Notify notifies all Observer to make modifications (call Update).

two. For example

One of the most common examples is that when we analyze the same set of data, we want to be able to provide a variety of representations (such as tables for statistical display, histogram statistics, percentage statistics, etc.). These representations all depend on the same set of data, of course we need to change the data, all the statistical display can be changed at the same time.

The structure diagram is as follows:

Datasubject: We think it's raw data.

Sheetobserver: It is considered a form that is used to display raw data.

Chartobserver: think of it as a chart, but also to display raw data.

The code is as follows:

Observer base class Observer {Public:virtual ~
	Observer () {} virtual void Update (subject* sub) = 0;
	
virtual void Printinfo () = 0;
	Protected:observer () {_st = ' ";
} string _st;

}; Notification base class Subject {public:virtual ~s
	Ubject () {}//register observer, so that the notification can notify the observer virtual void Attach (observer* obv) {_obvs->push_front (obv);
	}//Logoff observer, the notifying person no longer notifies the observer of virtual void Detach (observer* obv) {if (obv!= NULL) _obvs->remove (obv);
		//notification operation, after notification for each registered observer, will call its own Update method virtual void Notify () {List<observer*>::iterator it;
		
		it = _obvs->begin ();
		for (; it!= _obvs->end (), it++) {(*it)->update (this);
	virtual void SetState (const string& ST) = 0;
	
Virtual String GetState () = 0;
	Protected:subject () {_obvs = new list<observer*>; } private:list<observer* >* _obvs;

}; Specific data-notifying person class Datasubject:public
	Subject {public:datasubject () {_st = ';
	} ~datasubject () {}//own State string GetState () {return _st;
	} void SetState (const string& st) {_st = st;
} private:string _st;

}; Data Table Viewer class Sheetobserver:public
	Observer {public:virtual subject* getsubject () {return _sub;
		}//constructor, register yourself in the notification Sheetobserver (subject* sub) {_sub = sub;
	_sub->attach (this);
		Virtual ~sheetobserver () {_sub->detach (this);
	if (_sub!= 0) Delete _sub;
	}//Update operation void Update (subject* sub) {_st = Sub->getstate ();//The specific data can be printinfo () from the Subject of the notifying person; } void Printinfo () {cout<< "Sheet observer ....
	"<<_sub->getstate () <<endl;
} private:subject* _sub;

}; Data Graph Viewer Class Chatobserver:pUblic Observer {public:virtual subject* getsubject () {return _sub;
		} chatobserver (subject* sub) {_sub = sub;
	_sub->attach (this);
		Virtual ~chatobserver () {_sub->detach (this);
		if (_sub!= 0) {delete _sub;
		}//Update operation void Update (subject* sub) {_st = Sub->getstate ();
	Printinfo (); } void Printinfo () {cout<< "Chat observer ....
	"<<_sub->getstate () <<endl;
} private:subject* _sub;


}; Test int main () {datasubject* sub = new  

	Datasubject ()//Data notification observer* O1 = new Sheetobserver (sub);//Table viewer observer* O2 = new Chatobserver (sub);//Chart Viewer
	Sub->setstate ("old data"),//Data Changes sub->notify ()//notify the notification Sub->setstate issued notice ("new data");

	Sub->notify (); O1->update (sub);
You can also call the update function by the observer itself return 0; }
Description:
1. In the implementation of Observer mode, Subject maintains a list as a container for all its observers. Every time the Notify operation is invoked, the Observer object in the list is traversed and the notification is changed (the update action of the call Observer) is broadcast.
2. Running the sample program, you can see that when the original data Subject in the state "old", the two observers who depend on it display "old", and when the original data state changes to "new", the two observers who depend on it also change to "new".
3. Observer and Subject can be seen to be coupled, but both sides of the coupling rely on abstraction, not on concrete.

three. The Observer model in MFC

The Observer mode is also used in the implementation of MFC's view/document structure.

Document is the notification in the schema, manages the data in the application, and view is the observer in the pattern, showing the data in the associated document to the given party. A list of pointers is defined in the CDocument class to hold the corresponding CView object, and a function is defined to update all CView objects in the linked list.

The structure is as follows:


The original code is as follows:

AFXWIN.h class Cdocument:public CCmdTarget {public://Operations void AddView (cview* pView);   Register operation Void Removeview (cview* pView);
		Logout operation//Update views (simple Update-dag only)//notification operation void UpdateAllViews (cview* psender, LPARAM lhint = 0L,

cobject* phint = NULL);                Protected:cptrlist m_viewlist;
	The list of views}//doccore.cpp void CDocument::AddView (cview* pView) {assert_valid (PView); ASSERT (pview->m_pdocument = NULL);   Must is already attached ASSERT (m_viewlist.find (pView, NULL) = NULL);          Must not being in List m_viewlist.addtail (PView); Add the ASSERT in the list (pview->m_pdocument = NULL);

	Must be un-attached pview->m_pdocument = this;    Onchangedviewlist ();
	Must be the "last thing" to the document} void Cdocument::removeview (cview* pView) {assert_valid (PView); ASSERT (pview->m_pdocument = = this);  Must is attached to US m_viewlist.removeat (M_viewlist.find (PView)); Remove Pview-&gt from a linked list; m_pdocument = NULL;    Onchangedviewlist (); Must be the "last thing" done to the document} void CDocument::UpdateAllViews (cview* psender, LPARAM lhint, cobject* PH
		int)//walk through all views {ASSERT (Psender = NULL | |!m_viewlist.isempty ());        Must have views if sent by one of them POSITION pos = getfirstviewposition ();
		Traverse all observers while (POS!= NULL) {cview* PView = GetNextView (POS);
		Assert_valid (PView);
	if (PView!= psender) pview->onupdate (Psender, Lhint, Phint); }
}
From the code we can see that the AddView and Removeview equivalent to the registration and logoff operations, updateallviews equivalent to notification operations, the notification operation will call each CView object OnUpdate, to update.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.