    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Taming Complexity: A Class Hierarchy Tale</title>
        <link>https://members.accu.org/index.php/journals/277</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #67 - Jun 2005 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c145/">67</a>
                    (8)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c145-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c145+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Taming Complexity: A Class Hierarchy Tale</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 June 2005 05:00:00 +01:00 or Thu, 02 June 2005 05:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id=
"d0e18"></a>Introduction</h2>
</div>
<p>Some years ago, I was involved in the design of the software for
a security system1. The software had to process events from various
sensor devices detecting motion in the building. However, consider
the operation of such a system installed in a typical office
building: obviously alarms shouldn't ring when people are in the
building during normal working hours. Actually that's not strictly
correct: there may be areas of the building that are normally off
limits, and so should be monitored in normal working hours.
Further, there may be cases when people are working during the
night in certain parts of the building. Clearly this security
system needed to be flexible - i.e. it needed a lot of
configurability designing into it. To this end I had the task of
designing a logic engine in support of configurability far beyond
the simple description given above.</p>
<p>From this design comes the class hierarchy shown in Listing
1.</p>
<div class="sidebar">
<p class="title c3">Listing 1: <tt class="classname">evaluator</tt>
Class Hierarchy</p>
<pre class="programlisting">
class evaluator
{
public:
  virtual ~evaluator();
  virtual bool evaluate() const = 0;
...
};

class common_evaluator : public evaluator
{
protected:
  common_evaluator(const trigger* t1, const trigger* t2)
  : one(t1), two(t2)
  {}

  const trigger&amp; trigger_1() const { return *one; }
  const trigger&amp; trigger_2() const { return *two; }

private:
  const trigger* const one;
  const trigger* const two;
};

class and_evaluator : public common_evaluator
{
public:
  and_evaluator(const trigger* t1, const trigger* t2)
  : common_evaluator(t1, t2)
  {}
private:
  virtual bool evaluate() const
  {
    return trigger_1().active() &amp;&amp; trigger_2().active();
  }
};

class or_evaluator : public common_evaluator
{
public:
  or_evaluator(const trigger* t1, const trigger* t2)
  : common_evaluator(t1, t2)
  {}

private:
  virtual bool evaluate() const
  {
    return trigger_1().active() || trigger_2().active();
  }
};
</pre></div>
<p>The trigger class represents a trigger event, i.e. an event that
potentially participates in the triggering of an alert. Motion
being detected in a certain area and a door that should be closed
being open, are both examples of triggers going active. Further, a
trigger can be a simple time interval, 1800-0800 for example - i.e.
not during daytime office hours. In the domain terminology, such
events are said to cause a trigger to &quot;go active&quot;. It is possible
that a single trigger event could trigger an alarm, motion being
detected in an off-limits part of the building, for example.
However, motion detected in certain (most) parts of the building
between 1800 and 0800 - i.e. a combination of two trigger events -
is the kind of combination of events requiring an alert to be
raised. This is where the evaluator class hierarchy comes in. I
don't propose to go any further into the problem domain analysis,
but it turns out that when two trigger events are of interest,
there are two cases where it may be necessary to raise an
alert:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The case where both triggers need to be active (logical AND),
and</p>
</li>
<li>
<p>The case where either or both triggers need to be active
(logical OR)</p>
</li>
</ul>
</div>
<p>The evaluator hierarchy shown in Listing 1 facilitates this, and
also leaves open the possibility of extending the system to handle
the logical XOR case. Note in passing, that I'm ignoring cases
where an alert is raised if only a single trigger goes active -
these do not form part of this illustration.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e44" id="d0e44"></a>The C++ Three
Level Hierarchy</h2>
</div>
<p>I've used the <tt class="classname">evaluator</tt> class
hierarchy and spent some time explaining it, because I like the
idea of a realistic example to work with. The above comes from a
real project, although what I've shown is a simplified version for
illustration purposes.</p>
<p>I'm using this hierarchy as an example of the three level
structures that are idiomatic in C++ class hierarchy design:
interface class (see [<a href="#Radford">Radford</a>] for an
explanation of the term) at the top, common (but abstract)
implementation in the middle, and the most derived classes forming
the (concrete) implementations.</p>
<p>However the tale of this hierarchy has a slight twist in it. Let
me just digress for the moment and look at another three level
hierarchy - one I trust will need no explanation.</p>
<p>The <tt class="classname">circular_shape</tt> hierarchy, shown
in Listing 2 on page 26, uses the three level approach already
discussed. However in this case, the <tt class=
"classname">common_circular_shape</tt> class (the middle class)
captures state common across the concrete (most derived) classes,
while the derived classes themselves have their own specific state.
Also, note the constructors: there is a lot of repetition of code
here, in fact the constructors of <tt class="classname">circle</tt>
and <tt class="classname">ellipse</tt> differ in name only.</p>
<div class="sidebar">
<p class="title c3">Listing 2: <tt class=
"classname">circular_shape</tt> Class Hierarchy</p>
<pre class="programlisting">
class circular_shape
{
public:
  virtual ~ circular_shape();

  virtual void move_x(distance x) = 0;
  virtual void move_y(distance y) = 0;

...
};
class common_circular_shape : public circular_shape
{
protected:
  circular_shape(const point&amp; in_centre)
  : centre_pt(in_centre)
  {}
  point centre() const;
...
private:
  point centre_pt;
};

class circle : public common_circular_shape
{
public:
  circle(const point&amp; in_centre, const distance&amp; in_radius)
  : common_circular_shape(in_centre), radius(in_radius)
  {}

  virtual void move_x(int x);
  virtual void move_y(distance y);
...
private:
  distance radius;
};

class ellipse : public common_circular_shape
{
public:
  ellipse(const point&amp; in_centre, const distance&amp; in_radius)
  : common_circular_shape(in_centre), radius(in_radius)
  {}

  virtual void move_x(distance x);
  virtual void move_y(distance y);
...
private:
  distance radius_1, radius_2;
};
</pre></div>
<p>Compare the <tt class="classname">circular_shape</tt> and
evaluator hierarchies. In the latter case, the concrete (most
derived) classes have no state of their own - all state is common
and captured in the common implementation. However, there is
something <tt class="methodname">and_evaluator</tt> and <tt class=
"methodname">or_evaluator</tt> have in common with <tt class=
"classname">circle</tt> and <tt class="classname">ellipse</tt>:
they are saddled with the repetitive constructor baggage. That is
to say, the derived classes must each have an almost identical
constructor just to initialise state that is kept entirely in a
base class. The areas of variability in <tt class=
"methodname">and_evaluator</tt> and <tt class=
"methodname">or_evaluator</tt> are:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The name of the constructor - everything else about the
constructors is the same for both classes</p>
</li>
<li>
<p>The two characters denoting logical operation in <tt class=
"methodname">evaluate()</tt>- other than that, the implementation
of this virtual function is exactly the same for both classes, and
the same would apply if an <tt class="classname">xor_evaluator</tt>
were ever to be added</p>
</li>
</ul>
</div>
<p>Everything else is the same between these two classes (and this
also applies to a future <tt class=
"classname">xor_evaluator</tt>).</p>
<p>This suggests a need to investigate ways of simplifying the
design. Herein is the subject matter for the rest of this
article.</p>
<p>I will investigate two ways to separate the commonality and
variability: one using delegation, and the other using static
parameterisation using C++ templates.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e126" id="d0e126"></a>Approach
Using Delegation</h2>
</div>
<p>This approach draws on the STRATEGY design pattern [<a href=
"#Gamma-">Gamma-</a>]. First, let's deal with the <tt class=
"methodname">evaluate()</tt> virtual function - I'm going to factor
out <tt class="classname">and_evaluator</tt> and <tt class=
"classname">or_evaluator</tt>'s implementations into <tt class=
"methodname">and_operation</tt> and <tt class=
"methodname">or_operation</tt> respectively, and derive these from
the interface class operation. The resulting hierarchy is shown in
Listing 3 on page 27.</p>
<div class="sidebar">
<p class="title c3">Listing 3: <tt class="classname">operation</tt>
Class Hierarchy</p>
<pre class="programlisting">
class operation
{
public:
  virtual ~operation();
private:
  virtual bool result(const trigger&amp; one, const trigger&amp; two) const = 0;
...
};
class and_operation : public operation
{
private:
  virtual bool result(const trigger&amp; one, const trigger&amp; two) const
  {
    return one.active() &amp;&amp; two.active();
  }
};


class or_operation : public operation
{
private:
  virtual bool result(const trigger&amp; one, const trigger&amp; two) const
  {
    return one.active() &amp;&amp; two.active();
  }
};
</pre></div>
<p>The <tt class="classname">evaluator</tt> class no longer needs
to be in a hierarchy. It now looks like Listing 4. This design has
the benefit that there is no need for repetitive constructor code
(the operation hierarchy is stateless). However there is a
disadvantage - the lifetimes of operation objects must now be
managed.</p>
<div class="sidebar">
<p class="title c3">Listing 4: Non-Hierarchical <tt class=
"classname">evaluator</tt> Class</p>
<pre class="programlisting">
class evaluator
{
public:
  evaluator(
    const trigger* trigger_1, const trigger* trigger_2, const operation* op_object)
  : t1(trigger_1), t2(trigger_2), op(op_object)
  {}

private:
  bool evaluate() const
  {
    return op-&gt;result(*t1, *t2);
  }

  const trigger* const t1;
  const trigger* const t2;
  const operation* const op;
};
</pre></div>
<p>This can be addressed by taking the evolution of this design one
step further - i.e. operations being stateless can be taken
advantage of and, instead of using classes, function pointers can
be used, as shown in Listing 5 on page 28.</p>
<div class="sidebar">
<p class="title c3">Listing 5: Function Pointers Replacing
Classes</p>
<pre class="programlisting">
bool and_function(const trigger&amp; one,const trigger&amp; two)
{
  return one.active() &amp;&amp; two.active();
}
...
class evaluator
{
public:
  evaluator(
    const trigger* trigger_1, const trigger* trigger_2, bool (*eval_op)(const trigger&amp;,
          const trigger&amp;))
  : t1(trigger_1), t2(trigger_2), op(eval_op)
  {}
private:
  bool evaluate() const
  {
    return op(*t1, *t2);
  }

  const trigger* const t1;
  const trigger* const t2;
  bool (*op)(const trigger&amp;, const trigger&amp;);
};
</pre></div>
<p>However even at this stage in the evolution of the design, a
crucial piece of commonality remains to be dealt with: the
<tt class="methodname">operation::result()</tt> virtual function
implementations still differ only in the two characters denoting
the logical operation.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e182" id="d0e182"></a>Approach
Using C++ Templates</h2>
</div>
<p>This approach mixes run time polymorphism with static
parameterisation. In C++ terms, it mixes classes that have virtual
functions, with templates. (See Listing 6 on page 28).</p>
<div class="sidebar">
<p class="title c3">Listing 6: <tt class="classname">evaluator</tt>
Class Using Templates</p>
<pre class="programlisting">
class evaluator
{
public:
  virtual ~evaluator();
  virtual bool evaluate() const = 0;
  ...
};

template &lt;typename relational_function&gt; class evaluator_implementor
  : public evaluator
{
public:
  evaluator_implementor(const trigger* trigger_1, const trigger* trigger_2)
  : t1(trigger_1), t2(trigger_2)
  {}

private:
  virtual bool evaluate() const
  {
    return relational_function()(t1-&gt;active(), t2-&gt;active());
  }

  const trigger* const t1;
  const trigger* const t2;
};
</pre></div>
<p>The <tt class="classname">evaluator</tt> interface (base) class
is just the same as it was in the original three level hierarchy we
started with, and this design does not introduce a second
hierarchy. The part that's changed is the derived classes - these
have been replaced by a single class template called <tt class=
"classname">evaluator_implementor</tt>, derived (publicly) from
<tt class="classname">evaluator</tt>. The <tt class=
"classname">evaluator_implementor</tt> class contains the state and
implements the <tt class="methodname">evaluate()</tt> virtual
function using a function object supplied as a template
parameter.</p>
<p>The idea is that <tt class="classname">and_evaluator</tt> and
<tt class="classname">or_evaluator</tt> can now be implemented in a
very straightforward manner using the standard library's <tt class=
"classname">logical_and&lt;&gt;</tt> and <tt class=
"classname">logical_or&lt;&gt;</tt> function object templates as
template arguments:</p>
<pre class="programlisting">
typedef evaluator_implementor&lt;std::logical_and&lt;bool&gt; &gt; and_evaluator;
typedef evaluator_implementor&lt;std::logical_or&lt;bool&gt; &gt; or_evaluator;
</pre>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e228" id="d0e228"></a>Advantages:</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The hierarchy is much simplified. A three level hierarchy has
been collapsed into a two level hierarchy and there is only one
class at each level!</p>
</li>
<li>
<p>There is only one implementation of evaluate() and only one
derived class constructor - thus eliminating the repetition of code
sharing much commonality.</p>
</li>
<li>
<p>The separation between commonality and variability is much more
clearly stated. C++ templates have been used to very effectively
express this separation of concerns. The structure is expressed in
a base class with one class template derived from it. The
implementation specifics are factored out into the template
parameter.</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e241" id=
"d0e241"></a>Disadvantages:</h3>
</div>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>With <tt class="classname">evaluator_implementor</tt> being a
class template, there is no way to avoid the implementation of
<tt class="methodname">evaluate()</tt> leaking into the client
code. This is not a major disadvantage and is unavoidable in some
template code. Nevertheless, I regard it as being more desirable
for such implementation leaks to be avoided if possible. There is a
straightforward mechanism for dealing with this, which I'll come
back to in a moment.</p>
</li>
<li>
<p>The final disadvantage is very much one of pragmatics. There are
still very few programmers out there who are comfortable with
templates and template techniques. Although more and more are
becoming familiar with the STL, this only requires the knowledge to
use a template, whereas the design under discussion requires the
confidence to write one. In practice this usually means that if a
development group has a programmer who is happy to design/write
this sort of code, the programmer may be discouraged from doing so
because other members of the group will not be comfortable with the
code. It is sadly ironic that most working C++ programmers are
likely to be happier with a design containing the noise of more
repetition of code (and hence more opportunity to make a mistake)
and less clarity of intent, just because it doesn't use a
template.</p>
</li>
</ul>
</div>
<p>Just before moving on, I need to illustrate the mechanism I
alluded to in the first <span class=
"bold"><b>disadvantages</b></span> point above.</p>
<p>Rather than following the traditional approach of placing the
<tt class="classname">evaluator_implementor</tt> class template in
a header file, it can be placed in an implementation (typically
<tt class="filename">.cpp</tt>) file. The <tt class=
"classname">and_evaluator</tt> and <tt class=
"classname">or_evaluator</tt> <tt class="literal">typedef</tt>s can
also be placed in this implementation file. Client code does not
need to see the class template definition, or the <tt class=
"literal">typedef</tt>s, because all use of objects is intended to
be via the <tt class="classname">evaluator</tt> interface class.
This still leaves us with a slight problem - how can client code
create <tt class="classname">and_evaluator</tt> and <tt class=
"classname">or_evaluator</tt> objects? Well, they can't do so
directly, but simple factory functions making it possible can be
provided. The code fragment in Listing 7 illustrates this.</p>
<div class="sidebar">
<p class="title c3">Listing 7: Factory Functions</p>
<pre class="programlisting">
// evaluator.h
class evaluator
{
public:
  virtual ~evaluator();
  virtual bool evaluate() const = 0;
  ...
};

evaluator* create_and_evaluator(const trigger* trigger_1, const trigger* trigger_2);
...
// evaluator.cpp
template &lt;typename relational_function&gt; class evaluator_implementor
  : public evaluator
{
public:
  evaluator_implementor(const trigger* trigger_1, const trigger* trigger_2)
  : t1(trigger_1), t2(trigger_2)
  {}
  ...
};

typedef evaluator_implementor&lt;std::logical_and&lt;bool&gt; &gt; and_evaluator;
typedef evaluator_implementor&lt;std::logical_or&lt;bool&gt; &gt; or_evaluator;

evaluator* create_and_evaluator(const trigger* trigger_1, const trigger* trigger_2)
{
    return new and_evaluator(trigger_1, trigger_2);
}
...
</pre></div>
<p>The definitions of the factory functions are in the same
implementation file as <tt class=
"classname">evaluator_implementor</tt>. Therefore, both
implementation and instantiation of this class template are in the
same file, and its definition is never required anywhere else in
the code.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e301" id="d0e301"></a>Finally</h2>
</div>
<p>When complexity occurs in design, attempts to pretend it isn't
there lead inevitably to trouble. Complexity can't be eliminated,
it must be managed.</p>
<p>While the delegation based approach had to be explored, it
didn't really buy us very much. It solved only the problem of
constructor code repetition, but introduced the extra problem of
managing more objects. Taking the approach one step further - i.e.
using function pointers - eliminated this problem but the problem
of repetitive constructor code remained.</p>
<p>The approach using C++ templates, however, is an excellent
illustration of managing complexity by moving it out of the code
and into the programming language. In stating the advantages and
disadvantages of this approach I made the point about most
programmers still not being happy to write templates. Templates are
actually a complex feature of the C++ language, and no doubt this
accounts for the reluctance of programmers to adopt them. However,
the benefit of including a complex feature in the language is borne
out in the design using templates - it is an excellent illustration
of the C++ language absorbing complexity, rather than allowing the
complexity to manifest itself in the actual code. This is the
approach I adopted for the design of the security system described
in the introduction.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e310" id=
"d0e310"></a>Acknowledgements</h2>
</div>
<p>Many thanks to Phil Bass and Alan Griffiths for their helpful
comments.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e315" id="d0e315"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Gamma-" id="Gamma-"></a>
<p class="bibliomixed">[Gamma-] Erich Gamma, Richard Helm, Ralph
Johnson and John Vlissides, <span class="citetitle"><i class=
"citetitle">Design Patterns: Elements of Reusable Object-Oriented
Software</i></span>, Addison-Wesley, 1995.</p>
</div>
<div class="bibliomixed"><a name="Radford" id="Radford"></a>
<p class="bibliomixed">[Radford] Mark Radford, &quot;C++ Interface
Classes - An Introduction&quot;, <span class="bibliomisc"><a href=
"http://www.twonine.co.uk/articles/CPPInterfaceClassesIntro.pdf"
target=
"_top">http://www.twonine.co.uk/articles/CPPInterfaceClassesIntro.pdf</a></span></p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
