dimanche 20 décembre 2020

Policy Based Design - Ideomatic way to deal with multitude of types, e.g. storing them in a container, iterating, etc

In the hello world example of policy based design from wikipedia we use a common interface HelloWorld and configure it with different policies through templates - so far so good:

int main() {
  // Example 1
  typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish>
      HelloWorldEnglish;

  HelloWorldEnglish hello_world;
  hello_world.Run();  // Prints "Hello, World!".

  // Example 2
  // Does the same, but uses another language policy.
  typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman>
      HelloWorldGerman;

  HelloWorldGerman hello_world2;
  hello_world2.Run();  // Prints "Hallo Welt!".
}

This is all very nice and elegant, but what is the idiomatic way of managing / storing a collection of such configurable objects? For example, one would like to write

std::vector< some_magic_type > seasons_greetings;  // What is the common type specifying the public interface only?
seasons_greetings.push_back(hello_world);  // which is of type HelloWorldEnglish
seasons_greetings.push_back(hello_world2); // which is of type HelloWorldGerman
for (greeting : seasons_greetings) {
  greeting.Run() // access only the public interface
}

In designing interfaces as base classes and deriving specialised implementations from them, I don't have this problem - I can always store pointers to the base class type - but I need to spell out all implementations leading to a whole lot of derived classes. Policy Based Design promised to alleviate the explosion of derived classes that comes with this by using templates to mix and match behavior. But I pay for this with a whole lot of different types.

There must be an idiomatic way to deal with this. Any insight is greatly appreciated.

P.S. I admit that I did not buy the book, but you might have guessed already. This answer suggests storing a collection implies an inheritance based design, but does it really?

Aucun commentaire:

Enregistrer un commentaire