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