    <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  :: Data Visibility</title>
        <link>https://members.accu.org/index.php/articles/926</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">CVu Journal Vol 11, #6 - Oct 1999</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/c76/">Journals</a>

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c129/">116</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;Data Visibility</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 06 October 1999 13:15:33 +01:00 or Wed, 06 October 1999 13:15:33 +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="d0e20" id="d0e20"></a></h2>
</div>
<p>One of the things that you are told when you first start
learning about classes in C++ is to put the data in the <tt class=
"literal">private</tt>/<tt class="literal">protected</tt> part of
the class and write functions to access and set the data. This is
all well and good as far as it goes.</p>
<p>Unfortunately, it often goes too far, and you get horrendous
classes with (say) 10 items of data and then 20 functions of the
form <tt class="methodname">ReadXX()</tt>/<tt class=
"methodname">SetXX()</tt> to read and set those data items. Really,
you might as well have made those data items public for all the
good the data 'hiding' did.</p>
<p>In general the data should be set during the construction of the
object. It should really only be changed by the object itself as a
result of a high level operation.</p>
<p>What does this mean in practice? Lets take an example of a
customer account record as defined in the class below (I've removed
a bunch of extraneous stuff from this, so that we can see the
essentials).</p>
<pre class="programlisting">
typedef int  UID_t;
class Account {
protected:
   long offset;      // Offset into accounts file
   int  status;      // The account current status
   char  name[MAX_USER_NAME];
                      // Account name
   UID_t  uid;        // Player's user id
// more stuff 
public:
   Account();
   Account(int fd);
   UID_t  UID()      { return(uid); }
   int  Status()      { return(status); }
   const char *Name()    { return(name); }
   bool  IsNew()  
    { return((offset == -1L) ? true : false); }
   bool Save(int fd);
   // more stuff
};
</pre>
<p>The thing we want to look at is how we would save this record
out to file. The first method would be for the object that is
holding the list of records to ask the account for its offset into
accounts file and then save the record to that offset. You would
need to, at the least, provide a function that returned the
offset.</p>
<p>Frankly this is all pretty undesirable - you are exposing the
inner workings of the <tt class="classname">Account</tt> class to
other classes, even if formally the data is hidden.</p>
<p>A much better solution is for the <tt class=
"classname">Account</tt> class to have a <tt class=
"methodname">Save()</tt> member function of its own. The <tt class=
"methodname">Save()</tt> function uses <tt class=
"varname">offset</tt> to put its data into the file, and if you
later change the way you do things, you won't have to track down
all the places that save out records to disk and alter them.</p>
<p>There is an interesting wrinkle about this class. If the record
is a new one - i.e. it hasn't been written out to disk yet - then
the offset is set to <tt class="literal">-1L</tt> by the
constructor.</p>
<p>Now, the object that holds all these records needs to know if
this is a new record or not. So, in spite of everything, the first
cut through this code did indeed have a read function that read the
value of offset. It was only when I reviewed the code that the
absurdity of the whole thing struck me.</p>
<p>The calling function doesn't give a hoot what the value of
offset is - it just wants to know if this is a new account. Hence
the boolean <tt class="methodname">IsNew()</tt> function. This
inline function currently tests the value of offset to see if it is
<tt class="literal">-1L</tt> and reports accordingly. But the nice
thing is that if we decide to change the way we mark a record as
new, then all we need to do is to rewrite the <tt class=
"methodname">IsNew()</tt> function, nothing else in the program is
affected!</p>
<p>The more eagle eyed will have noticed that there are some inline
accessor functions in this class, and you may be wondering how I
justify them. Well, really it is a judgement call, and the longer
you are programming, the easier it will become. (Note that there
are no functions to set the individual data members, though.)</p>
<p>We can, however, draw out a guideline by looking at the
difference between the offset data member, which doesn't have an
accessor, and the name data member, which does.</p>
<p>The difference lies in the fact that the name of an account is a
'real life' attribute of an account, whereas the offset is merely
an artefact of the way we have organised the account data on file.
The name of the account is meaningful outside of the class, whereas
offset isn't.</p>
<p>That's not to say that all the 'real life' members should be
exposed in this way - you still need to be careful. In this case I
need to know the name and the uid so I can build indices with them
as keys (STL rules OK!). On the other hand it is very difficult to
think of any justification for exposing members that are part of
the internal plumbing outside of the class.</p>
<p>Not that I wish to be dogmatic about this &#9786;</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
