2016-04-28 7 views
11

У меня есть моделирование, которое работает на определенной высоте и определенной температуры:Какой шаблон дизайна используется для создания нескольких симуляций?

interface IGeneratable 
{ 
    string Name { get; } 
    void Generate(); 
}  

interface ISimulation : IGeneratable 
{ 
    int Height { get; } 
    int Temperature { get; }   
} 

Generate() процесс моделирования обычно включает в себя несколько шагов:

void Generate() 
{ 
    Step1(); 
    Step2(); 
    Step3(); 
} 

Теперь это возможно для пользователя для задания нескольких высот и/или нескольких температур.

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

interface IMultiSimulation : IGeneratable 
{ 
    ISimulation[] SubSimulations { get; }  
} 

Однако, в этом случае, суб-моделирования генерируют() отклоняется от порядка Шаг 1, Шаг 2, Шаг 3:

  • Если указано несколько температур, то Step2() должна быть выполнена только один раз для всех под-симуляций, а не для температуры (т. е. один раз для мультимоделирования).
  • Если указано несколько высоты, то:
    • Step1() предварительно сначала вычисляется для всех суб-моделирования.
    • Шаг 2, Шаг 3 и т. Д. Затем выполняются.
  • Возможно иметь большое моделирование с несколькими высотами и несколькими температурами. Это означает, что необходимо выполнить 2 вышеуказанных критерия.

Общие замечания

  • реализация для шага воплощен в IStep, который реализует IGeneratable. Таким образом, для моделирования можно, например, вернуть список шагов.
  • Количество шагов может быть довольно большим.

Я пытался использовать узор декоратора, но безуспешно.

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

Спасибо.

+1

Интерфейс моделирования, который абстрагирует одно или несколько симуляций, звучит как [Composite] (https://sourcemaking.com/design_patterns/composite). – jaco0646

ответ

0

его мне кажется, есть очень конкретный случай использование для реализации, так что я предлагаю использовать класс, который будет включать в себя imlementation для Сформировать() (я надеюсь, я понял требование справа)

class Simulation 
{ 
    string Name { get; } 
    int[] Heights { get; } 
    int[] Temperatures { get; } 

    void Generate() { 
     for (int i = 0; i < Temperatures.Count; i++) { 
      for (int j = 0; j < Heights.Count; j++) { 
        GenerateStep1(); 
      } 
      GenerateStep2(); 
      GenerateStep3(); 
     } 
    } 
} 
+0

Это не сработает, потому что GenerateStep2() должен запускаться только один раз. – alhazen

1

В вашем Я использовал бы шаблон дизайна. Метод generate будет проверять, имеет ли он какие-либо компоненты. Если это не так, то просто позвоните по телефону

void Generate() 
{ 
    Step1(); 
    Step2(); 
    Step3(); 
} 

но если у него есть компоненты, это означает, что у него есть несколько симуляций.Тогда код будет что-то вроде:

void Generate() 
{ 
if(this.simulations.Count==0) 
{ 
    Step1(); 
    Step2(); 
    Step3(); 
} 
else 
{ 
    if(multipleHeights) 
    { 
     precomputeStep1(); 
     if(multipleHeights) 
     { 
     createSingletonForStep2(this); 
     } 
     else 
     { 
     Step2(); 
     } 
     Step3(); 
    } 
    } 
} 

И для шага 2 я бы просто вызвать синглтон, который принимает этот композит в качестве параметра, так что для этой группы моделирования будет только один step2.

1

Интерфейсы:

interface IGeneratable 
{ 
    string Name { get; } 
    void Generate(); 
} 

interface IGeneratableOnce : IGeneratable 
{ 
    bool HasRunned { get; set; } 
} 

interface ISimulation : IGeneratable 
{ 
    int Height { get; } 
    int Temperature { get; } 
    IMultiSimulation MultiSimulation{ get; } 
    IGeneratable[] Steps{ get; } 

} 

interface IMultiSimulation : IGeneratable 
{ 
    ISimulation[] SubSimulations { get; }  
} 

Типичный MultiSimulation Генерировать:

void Generate(){ 
    for (ISimulation simulation in SubSimulations){ 
     simulation.Generate(); 
    } 
} 

Типичный ISimulation Генерировать:

void Generate(){ 
    for (IGeneratable step in Steps){ 
     step.Generate(); 
    } 
} 

ISimulation Генерировать избежать второй прогон Шаг дважды:

void Generate(){ 
    for (int i=0;i<Steps.Length;i++){ 
     IGeneratable step = Steps[i]; 
     if (i!=1){ 
      if (step is IGeneratableOnce && !(step as IGeneratableOnce).HasRunned){ 
       step.Generate(); 
       step.HasRunned = true; 
      } 
     }else{ 
      step.Generate(); 
     } 
    } 
} 

Вы можете добавить несколько других флагов, если хотите, возможно, даже какой-то метод вроде CanRun (int Height, int Temperature), если ваша логика становится слишком сложной. Однако в вашей ситуации, я считаю, вы должны использовать составное изменение шаблона, как этот образец кода.

EDIT: Here еще один интересный образец, который вы можете использовать

1

Ваша задача не так уж мало, так что ответ не один шаблон дизайна, но вместо этого несколько. Я лично не стал бы акцентировать внимание на шаблонах, а скорее на интуитивной и интенциональной реализации (например, я писал об этом здесь: http://www.tutisani.com/software-architecture/intuitive-object-models.html). Я думаю, что ваш дизайн не является интуитивным и самоописательным, поэтому вы не решаете правильную проблему, задавая вопрос, который вы задали.

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

  • Факт, что все ваши производные типы (в частности, интерфейсы) реализуют IGeneratable, который называется шаблоном проектирования Super Type.
  • Как было предложено, моделирование, содержащее другие моделирование внутри, представляет собой шаблон Composite. Однако это не совсем точно, поскольку IMultiSimulation не реализует ISimulation. В любом случае, это какой-то составной компонент, поскольку как родитель, так и дети реализуют IGeneratable по крайней мере.
  • IStep звучит как шаблон Strategy, но я думаю, вы не используете его правильно.

Теперь я хочу предложить вам пересмотреть свой подход к дизайну, потому что ваши интерфейсы не интуитивно понятны. Вот те вопросы, которые я вижу, которые вам нужно передумать:

  • ISimulation имеет высоту и температуру, а также имеет Generate(). Generate() скорее всего, предполагается использовать Height и Temperature - вот как я понял ваше описание, но тогда это не правильный способ выразить это. Если Generate() зависит от высоты и температуры, передайте их как аргументы и не определяйте их как свойства. Кроме того, интерфейс может лучше выражать поведение, а не состояние. Свойства представляют состояние, которое я бы назвал классом, а не интерфейсом.
  • Если симуляция будет выполнять шаги, не определяйте их сами по ISimulation - это опять не так интуитивно понятный дизайн.Передайте их как аргументы, и это сделает его шаблоном проектирования стратегии (поэтому я сказал выше, что он не реализован правильно).

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