Обсуждение статьи "Шаблоны проектирования в программировании на MQL5 (Часть 4): Поведенческие шаблоны 2"

 

Опубликована статья Шаблоны проектирования в программировании на MQL5 (Часть 4): Поведенческие шаблоны 2:

Статья завершает серию о шаблонах проектирования в области программного обеспечения. Я уже упоминал, что существуют три типа шаблонов проектирования - порождающие, структурные и поведенческие. Мы доработаем оставшиеся паттерны поведенческого типа, которые помогут задать способ взаимодействия между объектами таким образом, чтобы сделать наш код чистым.

Напоминание (Memento)

Шаблон можно использовать для экстернализации состояния объекта, чтобы обеспечить функцию отката (rollback). Он также известен как токен.

Что делает шаблон?

Мы можем применить шаблон, когда нам нужно сохранить снимок состояния объекта, который будет восстановлен позднее, и когда прямой интерфейс для получения состояния может раскрыть детали выполнения и нарушить инкапсуляцию объекта. Таким образом, шаблон будет захватывать и экспортировать состояние объекта для последующего восстановления. Ниже представлена диаграмма структуры этого шаблона, показывающая, как он может работать:

Напоминание (Memento)

Автор: Mohamed Abdelmaaboud

 

Спасибо за эту замечательную статью.

Я думаю, что я реализовал шаблон стратегии в советнике, но, возможно, другим способом.

Это может дать более практический пример для наших любимых читателей, а для меня, возможно, я хотел бы получить вашу обратную связь, если я допустил концептуальные ошибки:

Я упрощу процесс:
Сам эксперт является объектом и становится Контекстом:

  • У меня есть Enum, чтобы иметь возможность выбирать стратегию (как пример STRATEGY_RSI, STRATEGY_MA,...)
  • У меня есть оператор switch в OnInit(), на перечислении стратегий, и в зависимости от результата, я

switch(strategyName)
        {
         case STRATEGY_RSI :
            m_strategy = new Strategy_RSI();
            break;
         case STRATEGY_MA :
            m_strategy = new Strategy_MA();
            break;
         default:
            break;
}

  • Я устанавливаю входные параметры в стратегию через объект параметров (например, mqlparams).
[...]
// add the signal parameters to the strategy through the expert Method
Expert.AddParameterObject(signal_RSI_Params); // signal_RSI_Params is the parameter object that has the input parameters inside

//detail of the AddParameterObject method (simplified):
bool CExpert::AddParameterObject(CParameter & parameter)
  {
         if(!m_strategy.AddParameterObject(parameter))
           {
            return(false);
           }
     }
   return true;
  }

// add the generic expert parameters.
Expert.InitStrategyParameters(expert_1_Params);

//detail of the method  (simplified) :
bool CExpert::InitStrategyParameters(CParameter & expertParameters)
  {
// 
   if(!m_strategy.InitStrategyParameters(expertParameters))
     {
     [...]
      return false;
     }
   return true;
  }


  • Все стратегии реализуют одни и те же методы (открыть сигнал, закрыть сделку, ...)
  • Все стратегии могут загружать сигналы или свои пользовательские индикаторы

в функции OnTick эксперта я вызываю общие методы стратегии.

bool CExpert::CheckOpenLong(void)
  {
    [...]
    if(true == m_strategy.CheckOpenLong([...]))
     {
      [...]
     }
    [...]
}


Все работает отлично, я могу тестировать несколько стратегий/оптимизаций с одним и тем же экспертом.

Единственное, что я так и не выяснил, помимо размещения входных параметров в отдельном файле, это как динамически загружать входные параметры в зависимости от того, что пользователь выбирает в качестве данного конкретного входного параметра (т.е. входного параметра стратегии).


Я хотел бы получить ваши отзывы о том, как я это реализовал, является ли это шаблоном стратегии, или гибридом, что можно улучшить?

И есть ли у вас идея, как мы могли бы иметь (я не думаю, что это возможно в MT5) динамические контекстные входные параметры?


Большое спасибо

Дидма

 

очень поучительно

 

а почему одинаковые по функционалу функции имеют разные названия
например тут


void Memento::SetState(string state)
  {
   m_state=state;
  }
  
  
void Originator::State(string state)
  {
   m_state=state;
  }


 

Причина обращения: