Observer and iterator Modes -- the person who knows me is my concern, and I don't know what I want
The Chinese translation of the observer mode is the observer mode, which defines a one-to-many relationship between objects. When the State of an object changes, all objects dependent on it are notified and automatically updated. The connection points in COM are actually an observer mode. The connection points in COM are mainly provided for procedural languages. If we use C ++ to call COM components, then we can directly use the callback function to complete the same function. In fact, the specific implementation of the observer mode is also completed through the callback function. We still use examples to learn this mode.
Peter leaves and Peter leaves. The bank is busy and the center is shaken. If you know me, it means my worries. If you don't know me, it means what I want. Who are you here!
The leader leaves and the ear of the leader. The shopping spree is so powerful that the center is drunk. If you know me, it means my worries. If you don't know me, it means what I want. Who are you here!
The separation of the other, the reality of the other. The bank is in a tough position, and the center is like a mirror. If you know me, it means my worries. If you don't know me, it means what I want. Who are you here!
He started to get familiar with this poem from Feng Xiaogang's "no thief in the world. This poem is taken from "Wang Feng" in "The Book of Songs". The background of poetry is as follows. Zhou youwang, the last monarch of the Western Zhou Dynasty, is a zombie. He never laughed at his favorite takein. For the sake of the beauty of his smile, he played a game called "zhuhou. As a result, when the dogs attacked him, the beacon fire could no longer attract the rescue Army of the princes. He was killed by a dog, and finally buried at the foot of Lushan. After the end of the Western Zhou Dynasty, the successor Zhou pingwang was forced to migrate to the east, losing control of many princes. Then, when the old minister of the Zhou Dynasty went back to the old Western Zhou Dynasty, the Old City was lost and the Old City was full of scars. However, our example does not have much to do with this poem. I just think that "knowing me" can reflect the significance of the observer mode.
People always associate their mood with the surrounding areas. If they are in bad mood, the sky is no longer blue, and flowers and plants are no longer beautiful. In fact, nothing has changed. It's just your mood. However, in a virtual world, it is not difficult to let the world change with its own mood. When a person's mood changes, the sky and flowers around him change accordingly. Let's take a look at the class diagram:
From the class diagram, we can see that we have defined an observer interface, which is relatively simple. There is only one virtual function update. Its sub-classes sky and flower are also very simple, that is, update is implemented. We are looking at another subject interface, which has an observer list to store all the observers. Its method includes attach to add an observer, detach to delete an observer, and notify y is used to traverse all the observers and call their interface function update. Person is a specific class. In fact, all functions of subject can be implemented by it. But we should remember a rule: programming for interfaces, rather than implementing programming. This will facilitate the expansion of our program.
Let's take a look at the code. First, we need to define an observer interface, which is inherited by Tianhua mu. The Code is as follows:
# Ifndef _ observer1_h # DEFINE _ observer1_h // The Observer interface. The successor must implement the update method class observer {public: Virtual ~ Observer () {} virtual void Update (subject * pchange) = 0; protected: Observer () {}}; // Sky class sky: public observer {PRIVATE: // The specific target object pointer is used to change the behavior of the observer through its State. // there can be multiple specific target objects. However, here we provide a person * m_pperson; public: sky (person * pperson) {m_pperson = pperson; m_pperson-> attach (this);} virtual ~ Sky () {m_pperson-> detach (this);} void Update (subject * pchange) {// because there may be multiple, You need to determine if (pchange = m_pperson) {If (m_pperson-> getspirit () = true) {cout <"the sky is blue! "<Endl;} else {cout <" wooyun! "<Endl ;}}}; // flower class flower: public observer {PRIVATE: person * m_pperson; public: Flower (person * pperson) {m_pperson = pperson; m_pperson-> attach (this);} virtual ~ Flower () {m_pperson-> detach (this);} void Update (subject * pchange) {If (pchange = m_pperson) {If (m_pperson-> getspirit () = true) {cout <"When flowers bloom! "<Endl;} else {cout <" withered rose! "<Endl ;}}}; # endif
The above is the content of the observer. h header file, which defines an observer interface and is then inherited by a specific observer class. Let's take a look at the implementation of the target class.
Subject. content of the hfile: # ifndef _ subject_header1_h # DEFINE _ subject_header1_h // The class observer and subject must be nested and called, so it cannot be directly # include "Observer. H "// so you need to declare class observer first; // The Target Interface Class subject {public: // Add an observer virtual void attach (Observer *); // delete an observer virtual void detach (Observer *); // notify the observer virtual void dety (); protected: subject () {} PRIVATE: // observer list m_observerlist;}; // The target class person: public subject {PRIVATE: bool m_bgoodspirit; public: Person (): m_bgoodspirit (true) {} bool getspirit () {return m_bgoodspirit;} void goodspirit () {m_bgoodspirit = true; cout <"I am in a good mood, so I saw:" <Endl; notify ();} void badspirit () {m_bgoodspirit = false; cout <"I am in a bad mood, so I saw:" <Endl; notify () ;};# endif
This Code defines an interface of the target class. Of course, you can also define a person class to implement this function without using an interface, but in this way, you will not be able to observe multiple objects in the object of the observer's specific class.
(Because the Code contains Nested classes, I marked the file name of the Code. If you are not familiar with this usage, pay attention to it .)
Let's take a look at the specific implementation of the subject class:
The following is a subject. cpp file.
# Include "subject. H "# include" Observer. H "Void subject: attach (Observer * pobserver) {m_observerlist.push_back (pobserver);} void subject: Detach (Observer * pobserver) {m_observerlist.remove (pobserver);} void subject :: Y () {list: iterator ite; // You can traverse all the observers to notify for (ITE = m_observerlist.begin (); ite! = M_observerlist.end (); ++ ITE) (* ITE)-> Update (this );}
Because of nested usage, object of observer cannot be directly used in subject. H. It must be implemented in CPP, so we can separate it. The implementation here is actually quite simple. Let's take a look at the specific use.
#include "Observer.h"#include "Subject.h"int main(int argc, char* argv[]){Person p;Sky sky(&p);Flower flower(&p);p.GoodSpirit();p.BadSpirit();return 0;}
The running result is as follows:
In our example, the observer list is managed through the list of C ++ standard libraries, but to illustrate our next mode iterator, we will change it into an array. Let's take a look at the definition of iterator: it provides a method to access each element in an aggregate object sequentially, rather than exposing the internal representation of the object. In fact, iterator provides a Traversal method for containers such as arrays and linear tables. But now the standard library of C ++ has implemented this function well. We should use the standard library more. The. NET platform and Java Library also provide good container classes and iterators. Generally, we do not need to implement the iterator ourselves. But let's take a look at the specific implementation. To facilitate expansion, we also provide an iterator interface class:
template<class Item>
class Iterator{public:virtual bool hasNext() = 0;virtual Item Next() = 0;};
The interface provided here is relatively simple, just to determine whether there is an operation for the next element and return the operation for the next element. Generally, the iterator provides operations such as overload plus signs and equal signs, which are omitted here. I am not familiar with STL either. In the next stage, I want to learn about it. If you have time, I will share it with you.
Let's implement an array iterator:
Template <class item>
Class arrayiterator: Public iterator
{PRIVATE: // pointer to the array item * m_pitems; // int m_iposition of the current iterator; // Maximum length of the array int m_imaxsize; public: // initialization function arrayiterator (item * pitems, int imaxsize): m_pitems (pitems), m_iposition (0), m_imaxsize (imaxsize) {} bool hasnext () {// determine whether the current element is valid if (m_iposition <m_imaxsize & m_pitems [m_iposition]! = NULL) {return true;} else {return false;} item next () {// returns the current element, add the position to return m_pitems [m_iposition ++] ;}};
There is nothing complicated. Let's take a look at the implementation of the subject class:
// Target Interface Class subject {public: // Add an observer virtual void attach (Observer *); // delete an observer virtual void detach (Observer *); // notify the observer virtual void notify (); // create the iterator <Observer *> * createiterator () {return New arrayiterator <Observer *> (m_observerlist, 10 );} protected: subject (): m_iposition (0) {for (INT I = 0; I <10; I ++) m_observerlist [I] = NULL;} PRIVATE: int m_iposition; // Observer * m_observerlist [10];};
We can see that the current observer list is defined as Observer * m_observerlist [10]. Add a function for it:
// Create the iterator <Observer *> * createiterator () {return New arrayiterator <Observer *> (m_observerlist, 10 );}
This function helps us generate an iterator. Accordingly, the previous traversal function notify needs to be modified accordingly:
Void subject: Y () {// notify iterator <Observer *> * pobserver = createiterator (); While (pobserver-> hasnext () by traversing all the observers ()) {pobserver-> next ()-> Update (this);} Delete pobserver ;}
Here is the iterator we will introduce. In STL, The iterator has a good solution, which can be learned by Hou Jie's STL source code analysis. I am also preparing to read this book.
Now, let's talk about it first. Next, let's talk about the visitor mode.
References: 1. Design Patterns-design patterns-elements of reusable object-oriented software-Erich Gamma, translated by Li and other mechanical industry press 2, head first design patterns (photoprinting edition) freeman waits for the Southeast University Press 3, the Tao is natural-object-oriented Practice Guide, Wang Yonggang, Wang Yonggang, And the Electronics Industry Press 4, it turns out that the Book of Songs can read Tang Wen like this: Hebei Education Press