Proxy – structural design pattern – library MetaTrader 5

//+------------------------------------------------------------------+
//|                                                        Proxy.mqh |
//|                                    2019-2020, dimitri pecheritsa |
//|                                                 792112@gmail.com |
//+------------------------------------------------------------------+
//| proxy — structural design pattern                                |
//+------------------------------------------------------------------+
//   design patterns: elements of reusable object-oriented software
//   gof > erich gamma, richard helm, ralph johnson, john vlissides
//   published — 1994
//+------------------------------------------------------------------+
//| intent                                                           |
//+------------------------------------------------------------------+
//   provide a surrogate or placeholder for another object
//    to control access to it
//+------------------------------------------------------------------+
//| benefits                                                         |
//+------------------------------------------------------------------+
//   variable aspects > how an object is accessed, its location
//   code refactoring
//      problem > dependence on object representations/implementations
//      solution > hide the dependence from clients — 
//       keep changes from cascading
//         abstract factory, bridge, memento, proxy
//+------------------------------------------------------------------+
//| applicability                                                    |
//+------------------------------------------------------------------+
//   there is a need for a more versatile or sophisticated reference
//    to an object than a simple pointer
//      a remote proxy provides a local representative for an object
//       in a different address space
//      a virtual proxy creates expensive objects on demand
//      a protection proxy controls access to the original object
//         protection proxies are useful when objects should have
//          different access rights
//      a smart reference is a replacement for a bare pointer that
//       performs additional actions when an object is accessed
//         counting the number of references to the real object so
//          that it can be freed automatically when there are no more
//          references
//         loading a persistent object into memory when it's first
//          referenced
//         checking that the real object is locked before it's
//          accessed to ensure that no other object can change it
//+------------------------------------------------------------------+
//| structure                                                        |
//+------------------------------------------------------------------+
//
//      |Client|-------------------------->| Subject |
//                                         |---------|
//                                         |Request()|
//                                         |...      |
//                                              ^
//                                              |
//         +------------------------------------+------------...
//         |           real_subject             |
//   |RealSubject|<-----------------|         Proxy        |
//   |-----------|                  |----------------------|
//   |Request()  |                  |Request()             |
//   |...        |                  | ...                  |
//                                  | realSubject.Request()|
//                                  | ...                  |
//                                  |...                   |
//
//+------------------------------------------------------------------+
//| possible proxy structure at run-time                             |
//+------------------------------------------------------------------+
//
//   |aClient   |
//   |----------|          |aProxy        |
//   |Subject *-|--------->|--------------|           |aRealSubject|
//                         |realSubject *-|---------->|------------|
//                                                    |            |
//
#include <SRCPatternsPatternOrganizer.mqh>
namespace Proxy
{
//+------------------------------------------------------------------+
//| participants > subject                                           |
//+------------------------------------------------------------------+
class Subject
//   defines the common interface for real subject and proxy
//    so that a proxy can be used anywhere a real subject is expected
  {
public:
   virtual void      Request(void)=0;
  };
//+------------------------------------------------------------------+
//| participants > real subject                                      |
//+------------------------------------------------------------------+
class RealSubject:public Subject
//   defines the real object that the proxy represents.
  {
public:
   void              Request(void);
  };
//+------------------------------------------------------------------+
//| participants > real subject > request                            |
//+------------------------------------------------------------------+
void RealSubject::Request(void)
  {
   Print("real subject");
  }
//+------------------------------------------------------------------+
//| participants > proxy                                             |
//+------------------------------------------------------------------+
class Proxy:public Subject
//   maintains a reference that lets the proxy access the real subject
//      proxy may refer to a subject if the real subject and subject
//       interfaces are the same
//   provides an interface identical to subject's so that a proxy
//    can by substituted for the real subject
//   controls access to the real subject and may be responsible for
//    creating and deleting it
//      remote proxies are responsible for encoding a request and its
//       arguments and for sending the encoded request to the real
//       subject in a different address space
//      virtual proxies may cache additional information about the real
//       subject so that they can postpone accessing it
//      protection proxies check that the caller has the access
//       permissions required to perform a request
  {
protected:
   RealSubject*      real_subject;
public:
                    ~Proxy(void);
   void              Request(void);
  };
//+------------------------------------------------------------------+
//| participants > proxy > destructor                                |
//+------------------------------------------------------------------+
Proxy::~Proxy(void)
  {
   delete real_subject;
  }
//+------------------------------------------------------------------+
//| participants > proxy > request                                   |
//+------------------------------------------------------------------+
void Proxy::Request(void)
  {
   if(!CheckPointer(real_subject))
     {
      real_subject=new RealSubject;
     }
   real_subject.Request();
  }
//+------------------------------------------------------------------+
//| participants > client                                            |
//+------------------------------------------------------------------+
class Client:public ClientExample
  {
public:
   string            Output(void);
   void              Run(void);
  };
string Client::Output(void)
  {
   return __FUNCTION__;
  }
//+------------------------------------------------------------------+
//| collaborations                                                   |
//+------------------------------------------------------------------+
void Client::Run(void)
//   proxy forwards requests to realsubject when appropriate, 
//    depending on the kind of proxy
  {
   Subject* subject=new Proxy;
   subject.Request();
   delete subject;
  }
}
//+------------------------------------------------------------------+
//| output                                                           |
//+------------------------------------------------------------------+
//   Proxy::Client::Output
//   real subject
//+------------------------------------------------------------------+
//| consequences                                                     |
//+------------------------------------------------------------------+
//   introduces a level of indirection when accessing an object
//   a remote proxy can hide the fact that an object resides in a 
//    different address space
//   a virtual proxy can perform optimizations such as creating an 
//    object on demand
//   both protection proxies and smart references allow additional 
//    housekeeping tasks when an object is accessed
//   optimization — copy-on-write
//      copy the object only if it's modified
//      the subject must be reference counted
//      can reduce the cost of copying heavyweight subjects significantly
//+------------------------------------------------------------------+
//| implementation                                                   |
//+------------------------------------------------------------------+
//   overloading the member access operator — in c++
//   proxy doesn't always have to know the type of real subject
//      proxy can deal with all realsubject classes uniformly 
//       unless it is going to instantiate real subjects
//      some proxies have to refer to their subject whether it's 
//       on disk or in memory with address space-independent 
//       object identifiers
//+------------------------------------------------------------------+
//| related patterns                                                 |
//+------------------------------------------------------------------+
//   adapter  
//      provides a different interface to the object it adapts
//      proxy — same
//   decorator  
//      adds one or more responsibilities to an object
//      proxy — controls access to an object
//+------------------------------------------------------------------+
    📈 ROBOTFX MetaTrader Expert Advisors and Indicators to maximize profits and minimize the risks