Observer Pattern - page 3

 
nicholishen:

Yes, that's a pretty obvious solution, however, it'll break every time your terminal updates and the Object.mqh file is replace with the default CObject. 


Of course, if you use the std as it is. 
But you can also take it into your private folder and modify and extend it as you like. That's what I did.

 
Amir Yacoby:

Of course, if you use the std as it is. 
But you can also take it into your private folder and modify and extend it as you like. That's what I did.


Well there you go... not "useless" after-all :)

 
nicholishen:

Well there you go... not "useless" after-all :)


it's useless without muli inheritance but attaching it to the base of course serves as "another inheritance". But then some tweaks should be made to the code, because as is you can not attach them to CObject.

If you plan to inherit CObject from CObserver and CSubject than also you need to find a way. But what I mean is incorporate them inside CObject.
"
 
Amir Yacoby:

it's useless without muli inheritance but attaching it to the base of course serves as "another inheritance". But then some tweaks should be made to the code, because as is you can not attach them to CObject.

If you plan to inherit CObject from CObserver and CSubject than also you need to find a way. But what I mean is incorporate them inside CObject.
"

It's literally the same implementation but instead of using multiple-inheritance you're forking the super-class, which we all can agree is an inconvenience that takes an extra couple of minutes on a slow day.  I personally would rather take the extra time to fork my classes and preserve the integrity of the std lib, but if you want to alter CObject for convenience sake then that's your prerogative. The point is that we are discussing two relatively simple ways to work around the lack of multiple inheritance in order to make use of design patterns with existing classes.

 

It just dawned on me that you could also use an observer wrapper. 

class CObserverWrapper : public Observer
{
protected:
   CObject          *m_obj;
public:
   CObject          *Prev(void)                                    const { return m_obj.Prev(); }
   void              Prev(CObject *node)                                 { m_obj.Prev(node);    }
   CObject          *Next(void)                                    const { return m_obj.Next(); }
   void              Next(CObject *node)                                 { m_obj.Next(node);    }
   //--- methods for working with files
   virtual bool      Save(const int file_handle)                         { return m_obj.Save(file_handle);   }
   virtual bool      Load(const int file_handle)                         { return m_obj.Load(file_handle);   }
   //--- method of identifying the object
   virtual int       Type(void)                                    const { return m_obj.Type();      }
   //--- method of comparing the objects
   virtual int       Compare(const CObject *node,const int mode=0) const { return m_obj.Compare(node,mode);    } 
};


#include <ChartObjects\ChartObjectsLines.mqh>
class LineObserver : public CObserverWrapper
{
public:
   CChartObjectHLine line;
   LineObserver()
   {
      m_obj = GetPointer(line);
   }
   virtual void update() override
   {
      Print("Updating");
   }
};
 

As long as you don't inherit subject, the example is useless. Subject is not a standalone class.
This is why multiple inheritance is a requirement here, and I don't think your code bypass this - which is still possible.

 
Amir Yacoby:

As long as you don't inherit subject, the example is useless. Subject is not a standalone class.
This is why multiple inheritance is a requirement here, and I don't think your code bypass this - which is still possible.

My examples (changing class declarations) do the same thing as multiple inheritance but in a safer and less convenient way. Also, I needn't specify the details of a derived subject class since it is a requirement of the pattern and therefore implicit.
Reason: