Did I implement this pattern correctly? In this example, the document may close all open documents except itself. To do this, each document is assigned an Application to start with. Further, if necessary, the document sends a signal to the Application for the request to close all documents except for itself.

Requirement - the implementation should be based on an event interaction model.

class Application //типа наблюдатель (за документами) { std::vector<Document *> docs; public: void add_document(Document *doc) { docs.push_back(doc); } public slots: void close_non_active_docs_button_pressed(Document *active_doc) { для всех idoc кроме doc в this->docs idoc->close(); } } class Document { Application *app; public: void attach_to_app(Application *app) { this->curr_app = app; app->add_document(this); } void close(){...}; public signals: void close_non_active_docs_button_pressed(Document *active_doc); //////// //////// .... emit close_non_active_docs_button_pressed(this); } ///где то еще есть CONNECT(сигнал и слот) 

    2 answers 2

    In my opinion, the Document class does not need to store any information about the observer; in this case, new dependencies appear, which is not good at all. In addition, it would be good to inherit a Document from a general abstract class in which to register various signals for an observer (including a signal informing about the removal of an object so as not to keep incorrect references with the observer).

    The observer himself can also be done with a template (there will be a problem here, if inherited from QObject), or to keep in the list references to the general class (interface) of the observed objects.

      There is an entity document (Document class), in which there may be changes associated with the font, text, size, etc., etc., etc., etc., etc.

      This entity has a strong desire to signal these changes to outside listeners. But she (our essence) does not want to know too much about who she communicates with. Our document only wants to be heard using a special protocol (read the interface). Yes, this pattern begets egoists!

      Let's say this (this is a protocol for communicating with listeners):

       class AbstractDocumentChangedListener { public: virtual void fontSizeChanged(int was, int current) =0; virtual void fontNameChanged(string was, string current) =0; virtual void textChanged(string was, string current) =0; } 

      Having such a protocol we can register a listener in the list of listeners inside the object of our document:

       class Document { public: //... void addListener(AbstractDocumentChangedListener* listener) { _listeners.insert(listener); } //... private: set<AbstractDocumentChangedListener*> _listeners; } 

      Now everyone who wants to know what is happening with our document there should implement the corresponding interface:

       class DocumentListener : public AbstractDocumentChangedListener { public: void fontSizeChanged(int was, int current) override { //Теперь я знаю, что "они" изменили размер шрифта } void fontNameChanged(string was, string current) override { //Теперь я знаю, что "они" выбрали другой шрифт } void textChanged(string was, string current) override { // Другой текст? Хм, странно ) } } 

      And if I need not all the methods of this protocol?

       class SomeDocumentChangedListener : public AbstractDocumentChangedListener { public: void fontSizeChanged(int was, int current) {}; void fontNameChanged(string was, string current) {}; void textChanged(string was, string current) {}; } 

      And then:

       class DocumentListener : public SomeDocumentChangedListener { public: void textChanged(string was, string current) { //... } } 

      In any case, the registration of the listener in the target object will be as follows:

        //... Document doc; DocumentListener listener; doc.addListener(&listener); //... 

      In this way, this pattern is implemented very widely and is often used in Java. It can also be used in pure C ++.

      In Qt, this principle is implemented through the signals / slots system. Entities signal their internal changes with the help of emit, and, accordingly, students receive these changes with the help of slots implementation, respectively, establishing a connection between them (connect).