    <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  :: Reshaping an Old Piece of Design</title>
        <link>https://members.accu.org/index.php/articles/345</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>




<div class="xar-mod-head"><span class="xar-mod-title">Design of applications and programs + Overload Journal #56 - Aug 2003</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/articles/">All</a>

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c67/">Design</a>
<br />

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

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c156/">56</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c67-156/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c67+156/">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;Reshaping an Old Piece of Design</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 August 2003 22:56:32 +01:00 or Sat, 02 August 2003 22:56:32 +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="d0e16" id="d0e16"></a></h2>
</div>
<p>In C++, virtual functions are fundamental in supporting the
capability to implement an object-oriented design. They allow a
call to a member function made on a pointer/reference to a base
class to result in a member function of the object's concrete class
being called. In doing so, they are the language's fundamental
mechanism of run time polymorphism - the function actually called
depends on the type of the object pointed to, as determined at
<span class="emphasis"><em>run time</em></span>.</p>
<p>Sometimes being able to select a function to call based on the
run time type of <span class="emphasis"><em>one</em></span> object
is not enough. Sometimes there is a need to create the effect of a
function being virtual with respect to two or more objects. Some
languages (e.g. CLOS) have such a mechanism, and such functions are
known as <span class="emphasis"><em>multi-methods</em></span>.
However C++ has no such feature, and where multi-methods are
required in C++ the effect must be achieved using design and
programming techniques.</p>
<p>In this article I will first describe a problem I once faced,
that motivated me to take an interest in these techniques. I will
describe the solution I chose (which unfortunately was not a good
one) and the alternatives I considered, examining the tradeoffs
they offer. Then I will go on to look at the solution I would
choose if I faced the problem now, and explain why I would prefer
it.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e33" id="d0e33"></a>The
Problem</h2>
</div>
<p>A few years ago I was involved in the development of a package
for producing two-dimensional technical drawings. The drawing
program supported two basic shapes: straight lines, and
semicircular arcs, and it is easy to understand how the hierarchy
in the figure below was fundamental to the design.</p>
<div><img src="/var/uploads/journals/resources/radford1.JPG"></div>
<p>It is obvious that these shapes would need an interface capable
of supporting the operations the user is certain to expect, such as
being able to move the shapes around and rotate them. However,
because the program was for producing drawings of a technical
nature - essentially 2D CAD - an operation to calculate the
<span class="emphasis"><em>intersection</em></span> with another
shape was also necessary. Unfortunately having available a shape
abstraction is not good enough: the <tt class=
"methodname">intersection()</tt> methods need to implement the
intersection calculation formula, and implementing the formula
requires the concrete type of both shapes. In passing, it was to my
delight that I found Bjarne Stroustrup cites almost this very
problem as an example (in [<a href="#Stroustrup">Stroustrup</a>])
of where multimethods would be useful.</p>
<p>The solution I came up with at the time was not very good and
the irritating thing was that I knew I knew this - I just didn't
know what else to do. I could think of other approaches, but they
all seemed worse than the one I used. For example, some sources
(e.g. [<a href="#Meyers">Meyers</a>]) use the brute force approach
of downcasting in conjunction with RTTI. In hindsight though, the
RTTI approach offered a better set of tradeoffs.</p>
<p>This problem has been in my mind (on and off) ever since, and
years later, I have come up with what I think is a satisfactory
approach.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e57" id="d0e57"></a>Two Alternative
Solutions</h2>
</div>
<p>I considered two solutions at the time. One of them worked by
finding out the run time types of the shapes using run time type
information (RTTI); this could be described as a &quot;brute force&quot;
approach. The alternative used an object-oriented approach, and I
consider it to be a classic example of a solution being flawed
while being unquestionably object-oriented.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e62" id="d0e62"></a>Solution 1: The
RTTI Approach</h3>
</div>
<p>First consider what a fragment of the code to implement this
approach would look like. Here, dynamic_cast is used to check for
each possible type, and to provide the necessary downward
conversion (or downcast):</p>
<pre class="programlisting">
void intersection(const line&amp; l, const shape&amp; s,
                  intersection_points&amp; where) {
  if (const line* lp = dynamic_cast&lt;const line*&gt;(&amp;s)) {
    lines_intersection(l, *lp, where);
  }
  else if (const arc* ap = dynamic_cast&lt;const arc*&gt;(&amp;s)) {
    line_arc_intersection(l, *ap, where);
  }
  else
    //..
}

void intersection(const arc&amp; a, const shape&amp; s,
                  intersection_points&amp; where)
{ /* .. */ }
</pre>
<p>Now consider the consequences of adding a new specialisation of
<tt class="classname">shape</tt>, e.g. an elliptical arc. This
would mean two things:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Adding a new <tt class="methodname">intersection()</tt> function
overload.</p>
</li>
<li>
<p>Adding more code to the existing <tt class=
"methodname">intersection</tt> functions.</p>
</li>
</ol>
</div>
<p>In passing, note there is a historical twist to my rejection of
this solution: neither <tt class="literal">dynamic_cast</tt>, nor
any other form of RTTI for that matter (remember I said it was a
few years ago), were implemented in the compiler used on the 2D CAD
project! Therefore, this approach would have required the manual
implementation of some kind of an RTTI substitute (e.g. each class
having an integer constant to identify it).</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e92" id="d0e92"></a>Solution 2: A
Flawed Object Oriented Approach</h3>
</div>
<p>This is the solution I implemented at the time. It employs an
objectoriented mechanism of type recovery using virtual functions.
The mechanism takes advantage of the fact that an object's concrete
type is known within the member functions of the object's
class.</p>
<p>Let's look at a C++ fragment showing relevant parts of the shape
hierarchy's class definitions:</p>
<pre class="programlisting">
class shape {
public:
  virtual ~shape();
  virtual void intersection(const shape&amp; s,
                            intersection_points&amp; where) const = 0;
  virtual void intersection(const arc&amp; s,
                            intersection_points&amp; where) const = 0;
  virtual void intersection(const line&amp; s,
                            intersection_points&amp; where) const = 0;
  //...
};

class arc : public shape {
private:
  virtual void intersection(const shape&amp; s,
                            intersection_points&amp; where) const;
  virtual void intersection(const arc&amp; s,
                            intersection_points&amp; where) const;
  virtual void intersection(const line&amp; s,
                            intersection_points&amp; where) const;
  // ...
};

class line : public shape {
private:
  virtual void intersection(const shape&amp; s,
                            intersection_points&amp; where) const;
  virtual void intersection(const arc&amp; s,
                            intersection_points&amp; where) const;
  virtual void intersection(const line&amp; s,
                            intersection_points&amp; where) const;
  // ...
};
</pre>
<p>The <tt class="classname">shape</tt> class provides the
interface class heading up the hierarchy. Note that it has a
virtual function overload taking shape as a parameter, as well as
one for each of <tt class="classname">line</tt> and <tt class=
"classname">arc</tt>; if another type of shape (e.g. an elliptical
arc) were ever to be added to the hierarchy, <tt class=
"classname">shape</tt> would need a further virtual function taking
the new type as a parameter, and derived classes would need to
implement it. Therefore, this design is awkward to extend because
it would require a change to code in many of the files
participating in the implementation of the shape hierarchy.</p>
<p>The next code fragment shows what happens during an attempt to
find the intersection (if any) of objects of type <tt class=
"classname">line</tt> and <tt class="classname">arc</tt>:</p>
<pre class="programlisting">
shape* shape1 = new line(..);
shape* shape2 = new arc(..);

shape1-&gt;intersection(*shape2, where);
                     // Calls line::intersection()

void line::intersection(const shape&amp; s,
                        intersection_points&amp; where) const {
  s.intersection(*this, where);
  // Call is re-dispatched...
}

void arc::intersection(const line&amp; s,
                       intersection_points&amp; where) const {
  line_arc_intersection(s, *this, where);
  // ...and handled by the
  // arc::intersection()
  // overload that handles lines
}
</pre>
<p>The first call is made on an object of concrete type <tt class=
"classname">line</tt>, so the first virtual function implementation
entered is that of the overload <tt class=
"methodname">line::intersection(const shape&amp;, ..)</tt>. Note:
the type of the pointer returned by this is <tt class=
"literal">line*</tt> (rather than <tt class=
"literal">shape*</tt>).</p>
<p>Next, a call to <tt class="methodname">s.intersection(*this,
..)</tt> is made, and results in a call to the <tt class=
"methodname">intersection()</tt> overload taking a <tt class=
"classname">line</tt> as a parameter. Given that the pointer passed
in (i.e. <tt class="varname">shape2</tt>) points to an object of
concrete type <tt class="classname">arc</tt>, the result is a call
to <tt class="methodname">arc::intersection(const line&amp;,
..)</tt>. Now the concrete types of both objects is known.</p>
<p>Sadly this solution is flawed because, in a nutshell, it renders
derived classes intrusive not only on each other, but also on the
base class. It must be remembered that calculating intersection
points is only <span class="emphasis"><em>one</em></span> aspect of
shape functionality, yet providing it needs three virtual functions
in the interface of each class in the hierarchy.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e164" id="d0e164"></a>Towards A
Better Solution (?)</h2>
</div>
<p>In seeking a better solution, I'm going to start by asserting
that the flawed object oriented solution would actually have been
quite reasonable but for one thing: classes are <span class=
"emphasis"><em>intrusive</em></span> on each other. My point is
that this intrusiveness would not be such a problem if it could be
compartmentalised and therefore its impact limited. To this end I
will recruit the help of the EXTENSION OBJECT design pattern
(originally documented by Erich Gamma - see [<a href=
"#PLoPD3">PLoPD3</a>] for the full write-up). What follows is only
a brief and slightly C++ centric summary of the pattern, but the
description (below) of how it is used to implement a better
solution should complete the picture.</p>
<p><span class="bold"><b>Pattern</b></span></p>
<p>EXTENSION OBJECT.</p>
<p><span class="bold"><b>Context, problem and forces</b></span></p>
<p>Different clients will have different requirements of an
object's interface. The precise interface that will be required by
each client cannot always be anticipated at design time. Also, it
is often unacceptable to trade provision for them against the
interface bloat that would result. In C++ this problem can be
addressed to some extent by an approach using freestanding
functions. However this does not solve all the (potential) problems
(for example, freestanding functions cannot be virtual).</p>
<p><span class="bold"><b>Solution</b></span></p>
<p>Support the additional interfaces using separate objects and
give the <span class="emphasis"><em>Subject</em></span> an
interface for returning <span class="emphasis"><em>Extension
Objects</em></span>.</p>
<p><span class="bold"><b>Configuration</b></span></p>
<p>The extensions hierarchy (see figure below) is headed up by the
<tt class="classname">extension</tt> interface, while the
facilities the extension offers to clients are made available
through the interface <tt class=
"classname">specific_extension</tt>.</p>
<div><img src="/var/uploads/journals/resources/radford2.JPG"></div>
<p>The <tt class="classname">extension</tt> interface does not
support the operations required by the client, because different
extensions will offer different operations. Therefore client
obtains access to extensions via <tt class=
"methodname">get_extension()</tt>, to which it passes <span class=
"emphasis"><em>type</em></span>, where <span class=
"emphasis"><em>type</em></span> is simply some kind of indication
of the extension type being requested.</p>
<p><span class="bold"><b>Consequences</b></span></p>
<p>It can be seen that this pattern offers benefits in terms of
flexible extensibility, but there are some drawbacks, for
example:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Some of the behaviour of subject is moved out of it, so subject
no longer expresses all the behaviour that clients can perceive it
as having (whether this is a good or bad thing depends on the
actual behaviour).</p>
</li>
<li>
<p>The client code will need to recover the specific_extension
type. A typical method of doing so in C++ is by using <tt class=
"literal">dynamic_cast</tt>. Therefore, clients become more complex
in the face of the &quot;machinery&quot; needed to use the extensions. This
machinery can be encapsulated, but the issue still needs to be kept
in mind.</p>
</li>
</ol>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e237" id="d0e237"></a>Solution
Using Extension Objects</h2>
</div>
<p>The solution presented as a flawed object-oriented solution was
in some ways an attractive one, exhibiting the benefits of
objectoriented design, keeping code performing a function together
and separate from code performing other functions. It was only
flawed as a consequence of making classes within the shape
hierarchy intrusive on each other, and the interface clutter caused
(three virtual functions were needed in each class's interface).
Introducing EXTENSION OBJECT allows the same mechanisms to be
deployed while keeping the intrusiveness and interface clutter out
of the shape hierarchy. The design now looks as shown in the figure
below.</p>
<p>In this design, the following mappings from the EXTENSION OBJECT
configuration are used:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><tt class="classname">shape</tt>'s <tt class=
"methodname">create()</tt> method takes over from subject's
<tt class="methodname">get_extension()</tt> method. This is because
of a C++ object lifecycle issue that will soon become clear.</p>
</li>
<li>
<p><tt class="classname">shape_extension</tt> and <tt class=
"classname">shape_intersector</tt> assume the roles of <tt class=
"classname">extension</tt> and <tt class=
"classname">specific_extension</tt>, respectively.</p>
</li>
<li>
<p><tt class="classname">line_intersector</tt> and <tt class=
"classname">arc_intersector</tt> are the <tt class=
"classname">concrete_specific_extension</tt>s.</p>
</li>
</ul>
</div>
<p>As an aid to understanding these mappings, the names from the
configuration are used as <span class=
"emphasis"><em>stereotypes</em></span> in the exposition in UML
(see figure below).</p>
<div><img src="/var/uploads/journals/resources/radford3.JPG"></div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e287" id=
"d0e287"></a>Implementation</h2>
</div>
<p>The mechanics of recovering the types and working out the
intersection points are the same as in the flawed solution - the
only difference is that this time the participants are <tt class=
"classname">shape_intersector</tt>, <tt class=
"classname">arc_intersector</tt>, <tt class=
"classname">line_intersector</tt> and the additional <tt class=
"classname">shape_extension</tt>.</p>
<p>The class definition contains very little:</p>
<pre class="programlisting">
class shape_extension {
public:
  virtual ~shape_extension();
  // ...
};
</pre>
<p>It has a virtual destructor, but that needs no explanation:</p>
<pre class="programlisting">
namespace intersections {
class shape_intersector {
public:
  virtual ~shape_intersector();
  virtual void intersection(
                      const shape_intersector&amp; obj,
                      intersection_points&amp; where) const = 0;
  virtual void intersection(
                      const line_intersector&amp; obj,
                      intersection_points&amp; where) const = 0;
  virtual void intersection(
                      const arc_intersector&amp; obj,
                      intersection_points&amp; where) const = 0;
  // ...
};

boost::shared_ptr&lt;shape_intersector&gt;
  down_cast(
    boost::shared_ptr&lt;shape_extension&gt; obj);
}
</pre>
<p>The <tt class="classname">shape_intersector</tt> class is the
first one in the hierarchy to have an interface of any substance.
It declares <tt class="methodname">intersection()</tt> member
function overloads in much the same way as shape did in the flawed
object oriented solution - the difference here being that these
overloads take <tt class="classname">line_intersector</tt> and
<tt class="classname">arc_intersector</tt> parameters, in place of
<tt class="classname">line</tt> and <tt class="classname">arc</tt>
parameters respectively.</p>
<p>Another declaration of interest is that of the <tt class=
"function">down_cast()</tt> function: not a member of <tt class=
"classname">shape_intersector</tt> but provided within the
<tt class="classname">intersection</tt>s namespace. To understand
its role, first we need to look at <tt class=
"classname">shape</tt>:</p>
<pre class="programlisting">
class shape {
public:
  virtual void move_x(coordinate_units x) = 0;
  virtual void move_y(coordinate_units y) = 0;
  virtual void rotate(radians rotation) = 0;
  // ...
  virtual boost::shared_ptr&lt;shape_extension&gt;
  create(const std::type_info&amp; type) const=0;
};
</pre>
<p>The <tt class="classname">shape</tt> interface class provides
(besides the functional interface supporting user operations) a
virtual member factory function <tt class=
"methodname">create()</tt> that returns a <tt class=
"classname">shape_extension</tt> instance. Here there is a
deviation from the canonical EXTENSION OBJECT configuration,
because <tt class="classname">concrete_subject</tt> (<tt class=
"classname">line</tt> or <tt class="classname">arc</tt>, omitted
from the UML diagram) is designated as its owner, which is not
quite the case here. The design in this example uses the C++ idiom
of using a smart pointer to manage memory acquisition and release,
to avoid running into problems with object lifetimes.</p>
<p>Returning to <tt class="methodname">down_cast()</tt>: in order
to use the <tt class="classname">shape_intersector</tt> interface,
the <tt class="literal">shared_ptr&lt;shape_extension&gt;</tt>
instance returned from <tt class="methodname">shape::create()</tt>
must be converted to type <tt class=
"literal">shared_ptr&lt;shape_intersector&gt;</tt> (remember this
was listed as a consequence of the EXTENSION OBJECT design
pattern). A custom mechanism in the form of <tt class=
"methodname">down_cast()</tt> is provided to achieve this, because
unfortunately the use of a smart pointer cuts across the natural
approach of using <tt class="literal">dynamic_cast</tt>.</p>
<p>The definitions of classes <tt class="classname">line</tt> and
<tt class="classname">arc</tt> are self-explanatory: they just
provide implementations of <tt class="classname">shape</tt>'s
virtual member functions <tt class="methodname">move_x()</tt>,
<tt class="methodname">move_y()</tt>, <tt class=
"methodname">rotate()</tt> etc. I'm not going to list them here
because I don't believe they will actually add anything to the
illustration. Instead I'm going to move on to <tt class=
"methodname">intersection()</tt>, another freestanding function
declared within the intersections namespace:</p>
<pre class="programlisting">
namespace intersections {
intersection_points intersection(
                const shape&amp; s1, const shape&amp; s2) { // 1
  intersection_points where;
  boost::shared_ptr&lt;shape_intersector&gt; first
                = down_cast(s1.create(
                       typeid(shape_intersector))); // 2
  boost::shared_ptr&lt;shape_intersector&gt; second
                = down_cast(s2.create(
                       typeid(shape_intersector))); // 3
  first-&gt;intersection(*second, where);              // 4
  return where;
} }
</pre>
<p>Before looking at <tt class="methodname">intersection()</tt>'s
implementation, I feel it is worth digressing briefly to look at a
trade-off that has been made. It was observed that as a consequence
of the EXTENSION OBJECT design pattern, the machinery for obtaining
<tt class="classname">extension</tt> (<tt class=
"classname">shape_extension</tt>) instances and down casting them
to <tt class="classname">specific_extension</tt> (<tt class=
"classname">shape_intersector</tt>) adds complexity to clients. It
was also observed that one way to address this complexity is to
<span class="emphasis"><em>encapsulate</em></span> it, and this is
the approach taken here: i.e. it's all wrapped up in the <tt class=
"methodname">intersection()</tt> function. This encapsulation
introduces a tension with the design decision to create <tt class=
"classname">shape_extension</tt> instances on the heap (instead of
the originating object owning them): there is no way to preserve
these instances between calls to <tt class=
"methodname">intersection()</tt>. Thus efficiency is traded for
simplicity of usage (and tidiness of exposition in an article
:-)).</p>
<p>Getting back to <tt class="methodname">intersection()</tt>'s
implementation...</p>
<p>The function takes two <tt class="classname">shape</tt>
instances (by reference so they exhibit run time polymorphism),
<i class="parameter"><tt>s1</tt></i> and <i class=
"parameter"><tt>s2</tt></i>, as its parameters (statement 1).
Statements 2 and 3 create <tt class="varname">first</tt> and
<tt class="varname">second</tt>, these being the <tt class=
"classname">shape_intersector</tt> instances, and here two things
should be observed:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>The <tt class="methodname">shape::create()</tt> function is
called within the call to <tt class="function">down_cast()</tt> so
the instances, although present, never appear explicitly as type
<tt class="classname">shape_extension</tt>.</p>
</li>
<li>
<p>In the calls to <tt class="methodname">shape::create()</tt>, the
arguments are in both cases <tt class=
"literal">typeid(shape_intersector)</tt>, i.e. not the typeid of
the most derived classes. This is because the concrete classes
<tt class="classname">line</tt> and <tt class="classname">arc</tt>
know they must create <tt class="classname">line_intersector</tt>
and <tt class="classname">arc_intersector</tt> respectively - they
only need to be told they are creating extensions to a type
<tt class="classname">shape_intersector</tt>, as opposed to any
other type of extension.</p>
</li>
</ul>
</div>
<p>Statement 4 is where the intersections (if any) are calculated.
The rest of how this works is very similar to the way in which the
flawed object-oriented solution worked:</p>
<pre class="programlisting">
shape* shape1 = new line();
shape* shape2 = new arc();
</pre>
<p>And their intersections calculated:</p>
<pre class="programlisting">
intersection_points where =
intersection(*shape1, *shape2);
</pre>
<p>The workings of the <tt class="methodname">intersection()</tt>
function were explained above, so we now need to look at how
<tt class="methodname">line_intersector::intersection()</tt> and
<tt class="methodname">arc_intersector::intersection()</tt> work.
When <tt class="methodname">intersection()</tt> is called with
<i class="parameter"><tt>shape1</tt></i> and <i class=
"parameter"><tt>shape2</tt></i> as arguments, statement 4 in its
implementation results in a call to the <tt class=
"methodname">line_intersector::intersection()</tt> overload taking
a <tt class="classname">shape_intersector</tt> parameter:</p>
<pre class="programlisting">
void line_intersector::intersection(
               const shape_intersector&amp; s,
               intersection_points&amp; where) const {
  s.intersection(*this, where);
  // Call is re-dispatched...
}
</pre>
<p>Remember <i class="parameter"><tt>shape2</tt></i> has concrete
type <tt class="classname">arc</tt>, so re-dispatching the call
results in a call to <tt class=
"methodname">arc_intersector::intersection()</tt> - specifically,
the overload that takes a <tt class=
"classname">line_intersector</tt> as a parameter:</p>
<pre class="programlisting">
void arc_intersector::intersection(
               const line_intersector&amp; s,
               intersection_points&amp; where) const {
  line_arc_intersection(s, *this, where);
}
</pre>
<p>That's it. At this point the concrete types of both
shape_intersectors are known, and the calculation (details of which
we are not concerned with here) can be performed.</p>
<p>Phew!</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e563" id="d0e563"></a>Tradeoffs - In
Favour</h3>
</div>
<p>Intersection logic is non-intrusive with respect to the shape
hierarchy. In the case of the flawed object oriented solution, the
problem was that derived classes were intrusive on the base class,
and on each other. In the case of the solution that uses EXTENSION
OBJECTs, classes derived from <tt class=
"classname">shape_intersector</tt> are also intrusive on each
other, but there is a very important difference: there is no
intrusiveness on the shape hierarchy. For example: if another shape
is added, only the classes in the multi-methods hierarchy are
affected.</p>
<p>Note that, in the case of the example of adding another type of
shape (an elliptical arc for example), the bodies of existing
<tt class="classname">shape_intersector</tt> member functions will
not need their implementations changing. This is a consequence of
virtual functions being used to automate the control flow by
placing it in the hands of the C++ language. By contrast, in the
case of the RTTI solution, the control flow is implemented directly
in the code, and as a consequence adding the code for a new type of
shape means modifying existing code. In the former case, the
absence of a need to change existing code means that the chance of
introducing an error into it is reduced.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e576" id="d0e576"></a>Tradeoffs -
Against</h3>
</div>
<p>The <tt class="classname">shape</tt> and <tt class=
"classname">shape_intersector</tt> hierarchies have parallel
corresponding classes. Working with and maintaining such parallel
hierarchies always creates a balancing act of design.</p>
<p>The most obvious burden is the extra types that now inhabit the
design, and these must be managed - not just in physical terms but
also in addressing the communication issues that arise (more
documentation will be needed).</p>
<p>More subtle is the lack of any direct mention of intersections
in the shape interface, and in the interfaces of classes derived
from it. Here, a consequence associated with applying the EXTENSION
OBJECT design pattern haunts the design.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e591" id="d0e591"></a>In
Conclusion</h2>
</div>
<p>Using the object-oriented paradigm does not automatically make a
design superior. In the past object orientation has been adopted in
the hope that it would be the silver bullet that would solve all
software development problems. Of course, history now records that
nothing was further from the truth. There were many factors
involved, one being the lack of understanding of object orientation
itself. Another critical factor however, was the assumption that
being object oriented automatically made a design a good one. The
flawed object oriented solution presented earlier is an excellent
counter example.</p>
<p>An important lesson is that even good OOD has its costs. It
comes back to the fact that when solving problems with any level of
complexity, there is no such thing as a solution per-se - there are
options and tradeoffs.</p>
<p>Finally, the BSI C++ panel are currently discussing a proposal
by Julian Smith to add multi-methods to the language - therefore
this feature may or may not be present in the language when the
next edition of the standard appears. Full details of the proposal
can be found at Julian's web site (see [<a href=
"#Multi-Methods-Proposal">Multi-Methods-Proposal</a>]).</p>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e603" id="d0e603"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Boost" id="Boost"></a>
<p class="bibliomixed">[Boost] The Boost library (see <span class=
"bibliomisc"><a href="http://www.boost.org" target=
"_top">www.boost.org</a></span>)</p>
</div>
<div class="bibliomixed"><a name="Stroustrup" id="Stroustrup"></a>
<p class="bibliomixed">[Stroustrup] Bjarne Stroustrup,
T<span class="citetitle"><i class="citetitle">he Design and
Evolution of C++</i></span>, Addison-Wesley, 1994</p>
</div>
<div class="bibliomixed"><a name="Meyers" id="Meyers"></a>
<p class="bibliomixed">[Meyers] Scott Meyers, <span class=
"citetitle"><i class="citetitle">More Effective C++: 35 New Ways to
Improve Your Programs and Designs</i></span>, Addison-Wesley,
1996</p>
</div>
<div class="bibliomixed"><a name="Multi-Methods-Proposal" id=
"Multi-Methods-Proposal"></a>
<p class="bibliomixed">[Multi-Methods-Proposal] Julian Smith's
proposal for adding multimethods to C++ (<span class=
"bibliomisc"><a href="http://www.op59.net/cmm/readme.html" target=
"_top">www.op59.net/cmm/readme.html</a></span>)</p>
</div>
<div class="bibliomixed"><a name="PLoPD3" id="PLoPD3"></a>
<p class="bibliomixed">[PLoPD3] [PLoPD3] Robert Martin, Dirk Riehle
and Frank Buschmann (Editors), <span class="citetitle"><i class=
"citetitle">Pattern Languages of Program Design 3</i></span>,
Addison-Wesley, 1998.</p>
</div>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
