[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: OO design help
From:       "Nathan Bradshaw" <nathanlbradshaw () gmail ! com>
Date:       2008-07-18 22:54:12
Message-ID: 92af7fc70807181554x95969c4w77c1f1996939a451 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Fri, Jul 18, 2008 at 11:01 AM, Friedrich W. H. Kossebau <kossebau@kde.org>
wrote:

> Am Freitag, 18. Juli 2008, um 09:44 Uhr, schrieb Sebastian Trüg:
> > On Thursday 17 July 2008 19:57:10 Nathan Bradshaw wrote:
> > > On Thu, Jul 17, 2008 at 4:31 AM, Sebastian Trüg <trueg@k3b.org> wrote:
> > > > On Tuesday 15 July 2008 13:35:27 Nathan Bradshaw wrote:
> > > > > Hi all, one of the last things I want to do to finish up the KDE
> > > > > musicbrainz lib I've been building is to replace my local
> > > > > album/release/track classes with a set of interface classes that
> > > > > actual real software (rather than my toy test progs) can implement
> > > > > alongside whatever their native representation of music metadata
> is.
> > > > > My libs can
> > > >
> > > > then
> > > >
> > > > > just operate on this interface and I won't be duplicating (in a
> > > > > probably less functional way) the metadata structures in other
> > > > > applications.
> > > >
> > > > Just to clarify: are your libs using the interface or providing it?
> > >
> > > Providing it. My thinking on this is that rather than try and force
> > > people to implement a musicbrainz specific set of classes that will
> > > probably serve as nothing more than transfer points between the
> m/brainz
> > > service and the client app's own, more specialized, meta data class
> model
> > > my lib will just provide a set of abstract interface classes that
> client
> > > apps can then implement in what ever way makes most sense for them.
> > >
> > > The musicbrainz lib would then just have a bunch of functions that it
> > > performs against classes that implement the interface. The main
> > > operations would be creation and visiting combined with update /
> creation
> > > (for example when an existing local hierarchy is refreshed from the
> > > musicbrainz service, say when an artist releases a new album)
> >
> > I don't really get this. If your libs are providing the interface why
> would
> > clients implement it? The way I understand it the client would use the
> > interface the lib provides, ie. it calls methods from your interface.
> >
> > Or do you mean that the one interface should be provided by several
> > music-information libs or services, providing data from different sources
> > through one API?
> >
> > > > [If its the latter: Did you have a look at libkcddb (which has no
> > > > maintainer
> > > > AFAIK). Maybe you could build upon that?]
> > >
> > > Nope, haven't looked at the cddb lib, will do when I get home from work
> > > tonight.
> > >
> > > > > One thing that is getting me is when I try to come up with a way to
> > > > > represent container classes for things like an artist's release
> > > >
> > > > collection.
> > > >
> > > > > In an effort to not force implementation decisions on clients, it
> > > > > would seem that the way to go would be to specify a collection
> class
> > > > > that provided accessors, iterators etc and allow the client to
> > > > > specify the implementation (QList or what have you).
> > > > >
> > > > > My other concern is how to represent the relationship between a
> > > > > higher order class such as an artist and their release collection.
> Is
> > > > > it enough
> > > >
> > > > to
> > > >
> > > > > just specify in the artist interface that it return a reference to
> an
> > > > > object implementing the releasecollection interface? This scares me
> a
> > > > > bit as it means implementations will probably end up passing out
> > > > > handles to member data structures. Is this a valid concern for an
> > > > > interface designer or is that a problem that gets passed on to the
> > > > > client code?
> > > >
> > > > I think the proper encapsulation cannot be enforced completely be the
> > > > interface designer. One could still code a class that would expose
> > > > members. QT4 tends to return shared copies of almost everything. This
> > > > makes usage very
> > > > easy and you don't have to care about exposing internal data members
> > > > since changes will return in a deep copy.
> > > >
> > > > More after clarifying the question above. ;)
> > >
> > > I guess the area that I'm going back and forth on the most is how to
> > > model the container classes in a way that doesn't force implementation
> > > decisions on the client. If I define an interface that is essentially a
> > > subset of a typical QList type container class with the basic accessors
> > > and modifiers required for the lib to do it's job then clients can put
> > > regular containers, databases or any other type of back end behind it,
> > > which is what I'm looking for.
> > >
> > > WRT encapsulation, my concern is that an interface class such as
> IArtist
> > > would have to offer non-const access to an object that implements the
> > > IReleaseList container, which in turn leads to exposing the IArtist
> > > implementation's internals. Is this a valid concern?
> >
> > not really. It is pretty simple to solve this problem. Either with shared
> > copies or with a combination or const and non-const access methods.
> > Imagine this:
> >
> > class IArtist {
> > const IRelease* release( int i ) const:
> > IRelease* release( int i );
> > }
> >
> > or
> > class IArtist {
> >  IRelease release( int i ) const;
> >  IRelease& release( int i );
> > }
> >
> > Both allow to change a non-const Artist object while disallowing access
> to
> > a const one. The second one is more along the lines of the QT4 way.
>
> Even better would be to add a "const" prefix or similar to the const
> method's
> name, so in the application code the full semantic of the call is visible
> (cmp. the recent thread
> http://lists.kde.org/?l=kde-core-devel&m=121553407606530&w=2).


thanks for the link Friedrich.... ahh the joys of const-correctness :)


>
>
> So
> class IArtist {
> const IRelease* constRelease( int i ) const:
> IRelease* release( int i );
> }
>
> or
> class IArtist {
>  IRelease constRelease( int i ) const;
>  IRelease& release( int i );
> }
>
> Friedrich
>
> --
> Okteta - KDE Hex Editor, coming to you with KDE 4.1
>
> >> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to
> unsubscribe <<
>

[Attachment #5 (text/html)]

<div dir="ltr"><br><br><div class="gmail_quote">On Fri, Jul 18, 2008 at 11:01 AM, \
Friedrich W. H. Kossebau &lt;<a \
href="mailto:kossebau@kde.org">kossebau@kde.org</a>&gt; wrote:<br><blockquote \
class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt \
0pt 0.8ex; padding-left: 1ex;"> Am Freitag, 18. Juli 2008, um 09:44 Uhr, schrieb \
Sebastian Trüg:<br> <div><div></div><div class="Wj3C7c">&gt; On Thursday 17 July 2008 \
19:57:10 Nathan Bradshaw wrote:<br> &gt; &gt; On Thu, Jul 17, 2008 at 4:31 AM, \
Sebastian Trüg &lt;<a href="mailto:trueg@k3b.org">trueg@k3b.org</a>&gt; wrote:<br> \
&gt; &gt; &gt; On Tuesday 15 July 2008 13:35:27 Nathan Bradshaw wrote:<br> &gt; &gt; \
&gt; &gt; Hi all, one of the last things I want to do to finish up the KDE<br> &gt; \
&gt; &gt; &gt; musicbrainz lib I&#39;ve been building is to replace my local<br> &gt; \
&gt; &gt; &gt; album/release/track classes with a set of interface classes that<br> \
&gt; &gt; &gt; &gt; actual real software (rather than my toy test progs) can \
implement<br> &gt; &gt; &gt; &gt; alongside whatever their native representation of \
music metadata is.<br> &gt; &gt; &gt; &gt; My libs can<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; then<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; just operate on this interface and I won&#39;t be duplicating (in \
a<br> &gt; &gt; &gt; &gt; probably less functional way) the metadata structures in \
other<br> &gt; &gt; &gt; &gt; applications.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Just to clarify: are your libs using the interface or providing \
it?<br> &gt; &gt;<br>
&gt; &gt; Providing it. My thinking on this is that rather than try and force<br>
&gt; &gt; people to implement a musicbrainz specific set of classes that will<br>
&gt; &gt; probably serve as nothing more than transfer points between the \
m/brainz<br> &gt; &gt; service and the client app&#39;s own, more specialized, meta \
data class model<br> &gt; &gt; my lib will just provide a set of abstract interface \
classes that client<br> &gt; &gt; apps can then implement in what ever way makes most \
sense for them.<br> &gt; &gt;<br>
&gt; &gt; The musicbrainz lib would then just have a bunch of functions that it<br>
&gt; &gt; performs against classes that implement the interface. The main<br>
&gt; &gt; operations would be creation and visiting combined with update / \
creation<br> &gt; &gt; (for example when an existing local hierarchy is refreshed \
from the<br> &gt; &gt; musicbrainz service, say when an artist releases a new \
album)<br> &gt;<br>
&gt; I don&#39;t really get this. If your libs are providing the interface why \
would<br> &gt; clients implement it? The way I understand it the client would use \
the<br> &gt; interface the lib provides, ie. it calls methods from your \
interface.<br> &gt;<br>
&gt; Or do you mean that the one interface should be provided by several<br>
&gt; music-information libs or services, providing data from different sources<br>
&gt; through one API?<br>
&gt;<br>
&gt; &gt; &gt; [If its the latter: Did you have a look at libkcddb (which has no<br>
&gt; &gt; &gt; maintainer<br>
&gt; &gt; &gt; AFAIK). Maybe you could build upon that?]<br>
&gt; &gt;<br>
&gt; &gt; Nope, haven&#39;t looked at the cddb lib, will do when I get home from \
work<br> &gt; &gt; tonight.<br>
&gt; &gt;<br>
&gt; &gt; &gt; &gt; One thing that is getting me is when I try to come up with a way \
to<br> &gt; &gt; &gt; &gt; represent container classes for things like an \
artist&#39;s release<br> &gt; &gt; &gt;<br>
&gt; &gt; &gt; collection.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; In an effort to not force implementation decisions on clients, \
it<br> &gt; &gt; &gt; &gt; would seem that the way to go would be to specify a \
collection class<br> &gt; &gt; &gt; &gt; that provided accessors, iterators etc and \
allow the client to<br> &gt; &gt; &gt; &gt; specify the implementation (QList or what \
have you).<br> &gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; My other concern is how to represent the relationship between \
a<br> &gt; &gt; &gt; &gt; higher order class such as an artist and their release \
collection. Is<br> &gt; &gt; &gt; &gt; it enough<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; to<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; just specify in the artist interface that it return a reference \
to an<br> &gt; &gt; &gt; &gt; object implementing the releasecollection interface? \
This scares me a<br> &gt; &gt; &gt; &gt; bit as it means implementations will \
probably end up passing out<br> &gt; &gt; &gt; &gt; handles to member data \
structures. Is this a valid concern for an<br> &gt; &gt; &gt; &gt; interface designer \
or is that a problem that gets passed on to the<br> &gt; &gt; &gt; &gt; client \
code?<br> &gt; &gt; &gt;<br>
&gt; &gt; &gt; I think the proper encapsulation cannot be enforced completely be \
the<br> &gt; &gt; &gt; interface designer. One could still code a class that would \
expose<br> &gt; &gt; &gt; members. QT4 tends to return shared copies of almost \
everything. This<br> &gt; &gt; &gt; makes usage very<br>
&gt; &gt; &gt; easy and you don&#39;t have to care about exposing internal data \
members<br> &gt; &gt; &gt; since changes will return in a deep copy.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; More after clarifying the question above. ;)<br>
&gt; &gt;<br>
&gt; &gt; I guess the area that I&#39;m going back and forth on the most is how \
to<br> &gt; &gt; model the container classes in a way that doesn&#39;t force \
implementation<br> &gt; &gt; decisions on the client. If I define an interface that \
is essentially a<br> &gt; &gt; subset of a typical QList type container class with \
the basic accessors<br> &gt; &gt; and modifiers required for the lib to do it&#39;s \
job then clients can put<br> &gt; &gt; regular containers, databases or any other \
type of back end behind it,<br> &gt; &gt; which is what I&#39;m looking for.<br>
&gt; &gt;<br>
&gt; &gt; WRT encapsulation, my concern is that an interface class such as \
IArtist<br> &gt; &gt; would have to offer non-const access to an object that \
implements the<br> &gt; &gt; IReleaseList container, which in turn leads to exposing \
the IArtist<br> &gt; &gt; implementation&#39;s internals. Is this a valid \
concern?<br> &gt;<br>
&gt; not really. It is pretty simple to solve this problem. Either with shared<br>
&gt; copies or with a combination or const and non-const access methods.<br>
&gt; Imagine this:<br>
&gt;<br>
&gt; class IArtist {<br>
&gt; const IRelease* release( int i ) const:<br>
&gt; IRelease* release( int i );<br>
&gt; }<br>
&gt;<br>
&gt; or<br>
&gt; class IArtist {<br>
&gt; &nbsp;IRelease release( int i ) const;<br>
&gt; &nbsp;IRelease&amp; release( int i );<br>
&gt; }<br>
&gt;<br>
&gt; Both allow to change a non-const Artist object while disallowing access to<br>
&gt; a const one. The second one is more along the lines of the QT4 way.<br>
<br>
</div></div>Even better would be to add a &quot;const&quot; prefix or similar to the \
const method&#39;s<br> name, so in the application code the full semantic of the call \
is visible<br> (cmp. the recent thread<br>
<a href="http://lists.kde.org/?l=kde-core-devel&amp;m=121553407606530&amp;w=2" \
target="_blank">http://lists.kde.org/?l=kde-core-devel&amp;m=121553407606530&amp;w=2</a>).</blockquote><div><br>thanks \
for the link Friedrich.... ahh the joys of const-correctness :)<br> \
&nbsp;</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, \
204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br> <br>
So<br>
class IArtist {<br>
const IRelease* constRelease( int i ) const:<br>
<div class="Ih2E3d">IRelease* release( int i );<br>
}<br>
<br>
or<br>
class IArtist {<br>
</div>&nbsp;IRelease constRelease( int i ) const;<br>
&nbsp;IRelease&amp; release( int i );<br>
}<br>
<br>
Friedrich<br>
<font color="#888888"><br>
--<br>
Okteta - KDE Hex Editor, coming to you with KDE 4.1<br>
</font><div><div></div><div class="Wj3C7c"><br>
&gt;&gt; Visit <a href="http://mail.kde.org/mailman/listinfo/kde-devel#unsub" \
target="_blank">http://mail.kde.org/mailman/listinfo/kde-devel#unsub</a> to \
unsubscribe &lt;&lt;<br> </div></div></blockquote></div><br></div>



>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic