Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to prefer templated policy based design over non-templated inheritance based design

I am trying to understand the real requirement of the usage of templates for policy based design. Going through the new templated designs in C++ I found that policy based class design is a highly suggested way of design which allows you to 'plug-in' different behaviors from policy classes. A minimal example is the following (a shortened version of the wiki):

template <typename LanguagePolicy>
class HelloWorld : private LanguagePolicy
{
    using LanguagePolicy::message;

public:
    // Behaviour method
    void run() const
    {
        // policy methods
        cout << message();
    }
};

class LanguagePolicyA
{
protected:
    std::string message() const
    {
        return "Hello, World!";
    }
};
//usage
HelloWorld<LanguagePolicyA> hello_worlda;
hello_worlda.run(); // prints "Hello, World!"

A quick analysis shows that just to get different plugable methods message() we are inheriting from a templated type whose definition can be provided by anyone (and identified at compile time).

But the same level of abstraction (and configurable methods) can be achieved without using a templated code and by the simple old school run time polymorphism as shown below.

class HelloWorld
{
    LanguagePolicy *lp; //list of all plugable class
public:
    HelloWorld(LanguagePolicy *lpn) {
        lp = lpn;
    }

    // Behaviour method
    void run() const
    {
        // policy methods
        cout << lp->message();
    }
};
class LanguagePolicy
{
protected:
    virtual std::string message() const;
};

class LanguagePolicyA: LanguagePolicy
{
protected:
    std::string message() const
    {
        return "Hello, World!";
    }
};
//usage
HelloWorld helloworld(new LanguagePolicyA);
helloworld.run();

Functionality and level of abstraction wise I don't see much of a difference in the two approach (even though the second approach has few extra lines of code for LanguagePolicy, I think it is needed for the other users to know the interface; otherwise understanding LanguagePolicy depends upon the documentation). But I do think the later to be 'clean' (coming from someone who has not used template much). This is because personally in my opinion non-templated classes are cleaner to look at and understand. An extremely good example is the popular library VTK (Visualization Tool Kit) which solves many different problems using the second approach. Even though there are not extensive documentations of VTK, most of us - its users, can just have a look into its class diagrams (sometimes they are quite big) and deduce behaviors of classes; and develop highly configurable and complicated pipelines in our application (can't imaging VTK to be template based :)). The opposite is libraries like STL/BOOST which I don't think is possible for anyone to be able to identify the working of the classes without the use of extensive documentation.

So my question is, is the template based policy design really superior (only in this scenario of policy based design) than virtual inheritance based? If so, when and why?

like image 609
krips89 Avatar asked Jun 02 '15 13:06

krips89


1 Answers

Both are valid ways of structuring, it actually depends on the requirements. E.g.

Runtime vs compile time polymorphism.

When do you want/can/have to achieve polymorphism ?

Performance overhead of virtual calls

Templates generate code that has no indirections

The actual usage of the class.

When you have to store heterogenous collections, a base class is needed, so you have to use inheritance.

A very good book on policy-based design (a bit dated but good nevertheless) is Modern C++ Design

like image 126
Tasos Vogiatzoglou Avatar answered Oct 13 '22 00:10

Tasos Vogiatzoglou