The paper is structured as follows: Section 2 suc-
cinctly describes what policies means in C++ together
with their applicability. Section 3 presents the classi-
cal Decorator pattern with the associated challenges,
and the MixDecorator solution. In section 3.1 a C++
implementation of the MixDecorator pattern is ex-
plained, and Section 4 analyses the two new proposed
variants of the Decorator pattern. Conclusions and fu-
ture work are presented in section 5.
2 C++ POLICIES
Generally, a policy is defined as a class or class tem-
plate that defines an interface as a service to other
classes (Alexandrescu, 2001). A key feature of the
policy idiom is that, usually, a template class will de-
rive from (make itself a child class of) each of its pol-
icy classes (template parameters).
More specifically, policy based design implies the
creation a template class, taking several type param-
eters as input, which are instantiated with types se-
lected by the user – the policy classes, each imple-
menting a particular implicit interface – called pol-
icy, and encapsulating some orthogonal (or mostly or-
thogonal) aspect of the behavior of the template class.
Through policies the code is minimized, while
still allowing solutions for specific class related func-
tionalities. In (Alexandrescu, 2001) it is stated that
policy-based class design fosters assembling a class
with complex behavior out of many little classes
(called policies), each of which taking care of only
one behavioral or structural aspect. As the name sug-
gests, a policy establishes an interface pertaining to
a specific issue. It is possible to implement poli-
cies in various ways as long as the policy interface
is respected. Policies have been also described as a
compile-time(static) variant of the Strategy pattern.
For example, if we need to enlarge the capacity
of a container when a new element is added, we can
increase it with one or with half of the existing size
(or other strategies could be used, too). The strategy
will be chosen depending on the specific usage of the
container – Listing 1.
1 t e m p l a t e < c l a s s T >
2 c l a s s i n c r e m e n t E n l a r g e r {
3 p r o t e c t e d :
4 v o i d e n l a r g e ( i n t & c a p a c i t y ) {
5 c a p a c i t y ++ ;
6 }
7 }
8 t e m p l a t e < c l a s s T >
9 c l a s s h a l f E n l a r g e r {
10 p r o t e c t e d :
11 v o i d e n l a r g e ( i n t & c a p a c i t y ) {
12 c a p a c i t y += c a p a c i t y / 2;
13 }
14 }
15 t e m p l a t e < t y p e n a m e E n l a r g e P o l i c y >
16 c l a s s C o n t a i n e r :
17 p r o t e c t e d E n l a r g e P o l i c y {
18 .. .
19 p r o t e c t e d :
20 v o i d d o E n l a r g e () c o n s t {
21 e n l a r g e ( c a p a c i t y ) ;
22 .. .
23 }
24 .. .
25 };
Listing 1: An example of using policies.
Policies have direct connections with C++ template
metaprogramming and they have been used in many
examples; classical examples are: string class, I/O
streams, the standard containers, and iterators (Abra-
hams and Gurtovoy, 2003).
3 DECORATOR PATTERN
In (Gamma et al., 1994) book the Decorator pattern
is described as a pattern that provides a flexible al-
ternative to using inheritance for modifying behavior.
By using it we may add additional functionalities or
change the functionality of an object. This is a struc-
tural design pattern used to extend or alter the func-
tionality of objects by wrapping them into instances
of some decorator classes. Figure 1 presents the struc-
ture of its solution. It is generally agreed that deco-
rators and the original class object share a common
interface, and different decorators can be stacked on
top of each other, each time adding new functionality
to the overridden method(s).
Still, there are many situations when the decora-
tors need to add also new methods (i.e. methods that
are not in the initial object interface) that bring addi-
tional behavior; a very well known example is rep-
resented by the Java decorator classes for input and
output streams.
Since the interface IComponent defines only the
initial set of operations, the new added methods are
accessible only if they belongs to the last added dec-
orator, and the object is used through a reference of
that decorator type.
Also, removing and adding decorations at the run-
ning time is a requirement stated into the classical
pattern definition. Adding decorations is not difficult,
since they could be added on top. If we understand by
removing decorations that we can remove the top dec-
oration, then this is only possible if a method that re-
ENASE 2020 - 15th International Conference on Evaluation of Novel Approaches to Software Engineering
282