Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What design pattern to use for generating multiple simulations?

I have a simulation that runs at a specific height and a specific temperature:

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

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

The Generate() process for a simulation typically involves multiple steps:

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

Now, it is possible for the user to specify multiple heights and/or multiple temperatures.

In this case, multiple simulations (sub-simulations) are spawned off, one per each height/temperatue combination.

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

However, in this case, the sub-simulation's Generate() method deviates from the Step1, Step2, Step3 order:

  • If multiple temperatures are specified, then Step2() needs to be performed only once for all sub-simulations, and not per temperature (i.e. once per multi-simulation).
  • If multiple heights are specified, then:
    • Step1() is pre-computed first for all sub-simulations.
    • Step2, Step3,..etc are then performed.
  • It is possible to have a grand simulation with multiple heights AND multiple temperatures. This means that 2 above criteria need to be satisfied.

General notes

  • A step's implementation is encapsulated in IStep, which implements IGeneratable. So it is possible for a simulation to return a list of steps for example.
  • The number of steps can be fairly large.

I've been trying to use the decorator pattern but with no success.

I'm looking for a proper pattern with a scalable solution that would handle the generation of a single simulation as well as multiple simulations.

Thanks.

like image 725
alhazen Avatar asked Apr 28 '16 19:04

alhazen


1 Answers

In your case, I would use the design pattern composite. The generate method would check it it has any components. If it doesn't it will simply call

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

but if it does have components it means it has multiple simulations. Then the code will be something like:

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

And for the step 2 i would simply call a singleton that receives this composite as a parameter, so for this group of simulations there will be only one step2.

like image 174
bns Avatar answered Oct 28 '22 10:10

bns