Policy-based design
From Wikipedia, the free encyclopedia
Policy-based design is a computer programming technique summarized as a compile-time equivalent of the strategy pattern. Andrei Alexandrescu popularized this technique with his book Modern C++ Design (2001) and his column Generic<Programming> in the C/C++ Users Journal.
[edit] Overview
The technique is used to create a flexible set of types, providing the same interface, but employing different implementation behind. Therefore this technique has a lot of similarity to the strategy pattern. However while strategy allows the type to "change its ways" runtime, policy-based design fixes the implementation during compilation. In fact, it creates a new type for each different implementation. While their interface, functions present, names, and so on, will be the same, they will be different type — as opposed to strategy, where the same type behaves differently.
The main idea is to use commonality-variability analysis to divide the type into the fixed implementation and interface, the policy-based class, and the different policies. The main class, the policy-based class takes template arguments, types, templates of types, and so on, and delegates parts of the work to the policies.
The trick is to know what goes into the main class, and what policies should one create. Andrei's excellent article, mentioned above, gives us the clue: wherever we would need to make a possible limiting design decision, we should postpone that decision, we should delegate it to an appropriately named policy.
Policy classes can contain implementation, type definitions and so forth. Basically, the designer of the main template class will define what the policy classes should provide, what customization points they need to implement.
As we go by the analysis in policy-based design, it is a delicate task to create a good set of policies, just the right number. As little as necessary, but not less. The different customization points, which belong together, should go into one policy argument, such as storage policy, validation policy and so forth. A good rule of thumb during design is that you should be able to give a name to your policy, which represents a concept, and not one which represent an operation or some really tiny implementation detail. Persistence policy seems to be a good choice, while how to save policy does not.
As you do your policy-based design you will see how many other techniques will be useful, even if changed a bit, during your work. One example is that the template method pattern can be reinterpreted for compile time; so that your main class has a skeleton algorithm, which — at customization points — calls the appropriate functions of some the policies. You will also find yourself in using your policy classes as traits are used, asking type information, delegating type related tasks to it, a storage policy is one example where it can happen.
[edit] Simple example
Presented below is a simple example code written in C++.
#include <iostream> template <int I> struct policy { static const int i = I; }; template <class Policy = policy<0> > // default Policy is policy<0> struct host { void perform() { std::cout << "Using policy< " << Policy::i << " >" << std::endl; } }; int main() { host< policy<1> > a; a.perform(); }