Decorator Pattern in MQL5

 
//                                   DECORATOR
//                                   A way of sub-classing more functional objects, dynamically.
//
//                                   RULE
//                                   Open classes for extension and close for changes
//
//                                   Abstract Base Object
class A_Object
{
 protected:
  string m_name;
  //
 public:
  A_Object() : m_name("Unknown") {}
  virtual string Name() { return m_name; }
  virtual double Mass() = 0;
};
//                                   Abstract Decorator
class A_Decorator : public A_Object
{
 protected:
  A_Object* m_object;
  //
 public:
  ~A_Decorator()
  {
    if (CheckPointer(m_object) == POINTER_DYNAMIC) delete m_object;
  }
  virtual string Name() = 0;
};
//                                   Objects:
//                                   A
class C_ObjectA : public A_Object
{
 public:
  C_ObjectA() { m_name = "Object A"; }
  double Mass() { return 1.39; }
};
//                                   B
class C_ObjectB : public A_Object
{
 public:
  C_ObjectB() { m_name = "Object B"; }
  double Mass() { return 1.51; }
};
//                                   C
class C_ObjectC : public A_Object
{
 public:
  C_ObjectC() { m_name = "Object C"; }
  double Mass() { return 1.63; }
};
//                                   Decorators:
//                                   A
class C_DecoratorA : public A_Decorator
{
 public:
  C_DecoratorA(A_Object* object) { m_object = object; }
  string Name() { return m_object.Name() + " + Decorator A"; }
  double Mass() { return .07 + m_object.Mass(); }
};
//                                   B
class C_DecoratorB : public A_Decorator
{
 public:
  C_DecoratorB(A_Object* object) { m_object = object; }
  string Name() { return m_object.Name() + " + Decorator B"; }
  double Mass() { return .11 + m_object.Mass(); }
};
//                                   C
class C_DecoratorC : public A_Decorator
{
 public:
  C_DecoratorC(A_Object* object) { m_object = object; }
  string Name() { return m_object.Name() + " + Decorator C"; }
  double Mass() { return .13 + m_object.Mass(); }
};
//                                   Script
void OnStart()
{
  A_Object* object_a = new C_ObjectA;
  PrintFormat("%s: %g kg", object_a.Name(), object_a.Mass());
  //
  A_Object* object_b = new C_ObjectB;
  object_b           = new C_DecoratorA(object_b);
  object_b           = new C_DecoratorA(object_b);
  object_b           = new C_DecoratorC(object_b);
  PrintFormat("%s: %g kg", object_b.Name(), object_b.Mass());
  //
  A_Object* object_c = new C_ObjectC;
  object_c           = new C_DecoratorA(object_c);
  object_c           = new C_DecoratorB(object_c);
  object_c           = new C_DecoratorC(object_c);
  PrintFormat("%s: %g kg", object_c.Name(), object_c.Mass());
  //
  delete object_a;
  delete object_b;
  delete object_c;
}
/*
Output:

  Object A: 1.39 kg
  Object B + Decorator A + Decorator A + Decorator C: 1.78 kg
  Object C + Decorator A + Decorator B + Decorator C: 1.94 kg
*/
Files: