Jump to content

Policy-based design

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by BradAustin2 (talk | contribs) at 09:12, 18 January 2007. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Policy-based design, also known as policy-based class design or policy-based programming, is a computer programming paradigm based on an idiom for C++ known as policies. It has been described as a compile-time variant of the strategy pattern, and has connections with C++ template metaprogramming. It was first popularized by Andrei Alexandrescu with his 2001 book Modern C++ Design and his column Generic<Programming> in the C/C++ Users Journal.

Although the technique could theoretically be applied to other languages, it is currently closely associated with C++, and depends on its particular feature set. Furthermore, even in C++ it requires a compiler with sufficiently robust support for templates, which wasn't common before about 2003.

Overview

The central idiom in policy-based design is a class template (called the host class), taking several type parameters as input, which are instantiated with concrete types selected by the user (called policy classes), each implementing a particular implicit interface (called a policy), and encapsulating some orthogonal (or mostly orthogonal) aspect of the behavior of the resulting construct. By supplying a host class combined with a set of different, canned implementations for each policy, a library or module can support an exponential number of different behavior combinations, resolved at compile time, and selected by mixing and matching the different supplied policy classes in the instantiation of the host class template. Additionally, by writing a custom implementation of a given policy, a policy-based library can be used in situations requiring behaviors unforseen by the library implementor.

Policy classes have some similary to callbacks, but differ in that, rather than consisting of a single function, a policy class will typically contain several related functions (methods), often combined with state variables and/or other facilities such as nested types.

A policy-based host class can be thought of as a type of metafunction, taking a set of behaviors represented by types as input, and returning as output a type representing the result of combining those behaviors into a functioning whole. (Unlike MPL metafunctions, however, the output is usually represented by the instantiated host class itself, rather than a nested output type.)

A key feature of the policy idiom is that, usually (though it is not strictly necessary), the host class will derive (make itself a child class) of each of its policy classes using multiple inheritance. (An alternative is for the host class to merely contain a member variable of each policy class type; however the former approach has the major advantage that a policy class can add new methods, inherited by the instantiated host class and accessible to its users, which the host class itself need not even know about.) A notable feature of this aspect of the policy idiom is that, relative to object-oriented programming, policies invert the relationship between base class and derived class - whereas in OOP interfaces are traditionally represented by (virtual) base classes and implementations of interfaces by derived classes, in policy-based design the derived (host) class represents the interfaces and the base (policy) classes implement them. It should also be noted that in the case of policies, the class inheritance does not represent an "is a" relationship between the host and the policy classes. while this would traditionally be considered evidence of a design defect in OOP contexts, this doesn't apply in the context of the policy idiom.

A disadvantage of policies in their current implementation is that the policy interface doesn't have a direct, explicit representation in code, but rather must be described seperately and manually, in comments. This limitation will, however, be addressed by the type concepts feature proposed for the forthcoming version of the ISO C++ standard, known as C++0x.

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 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.