    <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  :: Observer Pattern Implementation</title>
        <link>https://members.accu.org/index.php/articles/364</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 #54 - Apr 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/c157/">54</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c67+157/">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;Observer Pattern Implementation</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 April 2003 22:57:19 +01:00 or Wed, 02 April 2003 22:57:19 +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="d0e27" id="d0e27"></a></h2>
</div>
<p>SH: I finally found some time to read your article series in
Overload 52&amp;53, and I've got some comments:</p>
<p class="c3"><span class="remark">PB: Thanks for spending the time
to provide some feedback. It's very much appreciated.</span></p>
<p>SH: I used to work on a framework that supported connections
between logic-gate-like objects in much the same way as you
describe. It was to be used in control systems in industrial user
interfaces (real physical knobs and buttons). Thus I think I've got
some experience to draw from.</p>
<p class="c3"><span class="remark">PB: Yes, that's exactly what we
have. In our case it's mainly buttons and lamps - very few
knobs.</span></p>
<p>SH: You wrestle with the problem of copying events (or the
objects that contain them). Funny enough that you say yourself that
you often try to solve the wrong problem if you find that the
solution seems elusive. I couldn't agree more. I think events
shouldn't have value semantics. Here's why:</p>
<p>You rightly associate an event with an output in a logic gate.
The logic gate would be represented by an object that contains the
event as a member object. What does it mean then to copy such a
gate with its event member? It would be much like copying a gate on
a schematic drawing, right? If you ever worked in hardware design,
you know that copying a gate gives you a gate of the same type but
with its pins detached. Copying a gate doesn't copy its
connections!</p>
<p class="c3"><span class="remark">PB: Absolutely. I haven't done
any electronics at all, but I have worked alongside electrical and
electronics engineers. And, I agree that copying a logic gate
wouldn't make sense if its connections were copied as
well.</span></p>
<p class="c3"><span class="remark">However, I'm interested in the
general problem of de-coupling objects in one software layer from
the higher-level objects that observe them. Perhaps there are some
objects for which a copy operation really should copy the
connections. I couldn't think of any specific examples, but I
suspected that different copy semantics would be appropriate for
different types of object. In particular, some objects shouldn't be
copyable at all.</span></p>
<p>SH: What it really boils down to is that a gate has a unique
identity (which is usually shown in schematics, i.e. &quot;U205&quot;). You
can't have two objects with the same identity. Copying a gate
creates a new gate with a new identity. Hence gates can not have
value semantics. The result is that storing them in STL containers
directly is a bad idea. You store pointers to them instead.</p>
<p class="c3"><span class="remark">PB: Now you're losing me. I'm
familiar with the idea of two broad categories of objects: 1) those
with value semantics and 2) those with reference semantics. I
appreciate, too, that identity is often of little or no importance
for objects in category 1, whereas it is usually crucial for
category 2 objects. However, I don't see why an object with
identity shouldn't have value semantics. And I would be quite upset
if objects with identity could/should not be stored in STL
containers.</span></p>
<p class="c3"><span class="remark">For example, what's wrong with a
std::vector&lt;Customer&gt;? Real customers certainly have identity
and I'd expect objects of the Customer class to have identity, too.
You might argue that it doesn't make sense to copy a Customer
(which is true), but it makes perfect sense to store Customers in a
vector, and that requires Customer objects to be copyable. My
Events are just like Customers: it makes no sense to copy them, but
perfect sense to store them in STL containers.</span></p>
<p>SH2: I do see a conflict between object identity and value
semantics. Let me quote from Josuttis' Standard Library Book (page
135): &quot;All containers create internal copies of their elements and
return copies of those elements. This means that container elements
are equal but not identical to the objects you put into the
container.&quot;</p>
<p>I think that this makes it quite clear that a
std::vector&lt;Customer&gt; might not be such a good idea. As a
further hint, consider what would happen if you'd like to hold a
customer in two containers at the same time (say, one that holds
all customers, and another that holds customers who are in
debt).</p>
<p>What I'm saying is that if the only reason to make a class
copyable is to be able to put them into STL containers, you're
probably trying to do the wrong thing.</p>
<p>SH: The pointers may well be smart pointers. The details depend
on your ownership model. It is not always necessary to use
reference counted pointers. If you have a different method to
ensure that connections are removed before the gates are deleted,
then a bare pointer may be adequate.</p>
<p class="c3"><span class="remark">PB: Agreed.</span></p>
<p>SH: Note that you don't necessarily need to prevent event
copying altogether. It may well be useful to be able to copy
events, but the key is that copying an event does not copy the
connections. I feel, however, that this style of copying is better
implemented through a separate clone function instead of the copy
constructor.</p>
<p class="c3"><span class="remark">PB: This really depends on
whether we choose value or reference semantics, I think. No, on
second thoughts, it depends on whether the objects in question are
polymorphic (the virtual function kind of polymorphism). The
value/reference semantics design decision is separate.</span></p>
<p>SH2: In the polymorphic case you have no choice but storing
pointers in the container anyway. Copy construction is not needed
here. If you nevertheless want to make copies of your objects, they
need a virtual clone member function. The value/reference decision
is not entirely separate, since you can not have value semantics
with polymorphism in the same object. If you wanted to model that,
you'd end up with a handle-body pair of objects, which is just
another variant of the smart pointer theme.</p>
<p>SH: Regarding event ownership I think that a hierarchical
ownership model may well be better than a distributed &quot;shared
ownership&quot; model. If we carry on a little longer with the hardware
analogy, I would propose to have a &quot;Schematic&quot; object that owns all
the gates in it. Deleting the schematic object deletes all
connections and gates. The problem then is reduced to &quot;external&quot;
connections that go between the schematic and the outside world.
Internal connections don't need to be implemented with smart
pointers.</p>
<p class="c3"><span class="remark">PB: Again, I agree that a
hierarchical ownership model has benefits. In fact, I suspect our
software could be improved by modeling the hardware more closely -
tools contain modules, which contain other modules, which contain
I/O boards - and the logic gates would be owned by the module that
contains them. In practice, though, this is not particularly easy
to do and I felt that discussing the short-comings of the existing
software would distract from the main point of the article. The
difficulty boils down to the difference you highlight, here.
External connections and internal connections are not
distinguished, so we would have to use a mechanism that supports
the more general ownership model for both.</span></p>
<p>SH2: It would certainly go too far for the purpose of the
article to introduce several levels of hierarchy. The point I was
hinting at however was that looking at the problem from one level
up in the hierarchy might render a different - and maybe more
adequate - design. The problem here is a general problem with the
observer pattern: Who owns/controls the connections? It is by no
means clear that it should be the subject that owns them. This
would be analogous to a chip on a PCB that owns the wires connected
to its outputs. Wouldn't it be more natural to think that all wires
belong to the PCB itself? Each output could still have a container
of pointers to connections for managing the updates, but it
wouldn't necessarily own them from a lifetime management
perspective.</p>
<p>Now, as you rightly point out, the hardware analogy isn't
necessarily always the right one. So it will likely depend on the
situation what kind of ownership model you would choose. This makes
me wonder whether it would be sensible and feasible for a general
purpose observer implementation to provide some latitude in this
respect, maybe through policies (in Alexandrescu's sense).</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
