[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:50:32
Message-ID: 92af7fc70807181550l6bcbb1fg65a008a8a5b38cd7 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Fri, Jul 18, 2008 at 3:44 AM, Sebastian Tr=FCg <trueg@k3b.org> wrote:

> On Thursday 17 July 2008 19:57:10 Nathan Bradshaw wrote:
> > On Thu, Jul 17, 2008 at 4:31 AM, Sebastian Tr=FCg <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 alongsi=
de
> > > > 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 t=
he
> > 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 wou=
ld
> clients implement it? The way I understand it the client would use the
> interface the lib provides, ie. it calls methods from your interface.


I think we might be having terminology issues :)

API wise, the lib provides what you'd expect: look up artist by name, get
album by CD ID that sort of thing. What I've be going on about though is th=
e
set of abstract base classes I'm knocking together that client code could
inherit from to interact with the library.

My thinking is, most client code is going to have an existing hierarchy of
some form already to represent the typical
MusicCollection->Artist->ReleaseCollection->Release->TrackCollection->Track
hierarchy and it could be implemented with any number of possible back ends=
.
For a situation like a CDDB or musicbrainz lookup of a CD etc there is not =
a
lot of overhead in creating the quite small object hierarchy to represent a
single release, but I think its a different story for an application like
say a music manager application. Lets say this Mythical Music Manager
provides a batch operation like trying to best guess identify all your badl=
y
labeled, possibly duplicated music files and which artist / album they
belong to. If you've already parsed the collection into a hierarchy, and
lets say its a big collection, and then you've walked that hierarchy and
sent off a big bunch of queries to musicbrainz you would then end up with a
second big hierarchy returned to you. Instead, if the MMM collection
hierarchy through either interface classes or multiple inheritance supporte=
d
it's own as well as the musicbrainz lib class models then the MMM collectio=
n
would be passed to and updated by the musicbrainz lib query functions.

I think I'm doing a really bad job of explaining this :(


>
>
> 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 t=
he
> > > > 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 modifie=
rs
> > 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 IArtis=
t
> > 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 t=
o
> a
> const one. The second one is more along the lines of the QT4 way.
>
> Cheers,
> Sebastian
>

Thanks Sebastian, I think that I was just over-thinking this issue!



>
>
> >> 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 3:44 AM, \
Sebastian Trüg &lt;<a href="mailto:trueg@k3b.org">trueg@k3b.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;"> <div class="Ih2E3d">On Thursday \
17 July 2008 19:57:10 Nathan Bradshaw wrote:<br> &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; On Tuesday 15 July 2008 13:35:27 Nathan Bradshaw wrote:<br>
&gt; &gt; &gt; Hi all, one of the last things I want to do to finish up the KDE<br>
&gt; &gt; &gt; musicbrainz lib I&#39;ve been building is to replace my local<br>
&gt; &gt; &gt; album/release/track classes with a set of interface classes that \
actual<br> &gt; &gt; &gt; real software (rather than my toy test progs) can implement \
alongside<br> &gt; &gt; &gt; whatever their native representation of music metadata \
is. My libs can<br> &gt; &gt;<br>
&gt; &gt; then<br>
&gt; &gt;<br>
&gt; &gt; &gt; just operate on this interface and I won&#39;t be duplicating (in \
a<br> &gt; &gt; &gt; probably less functional way) the metadata structures in \
other<br> &gt; &gt; &gt; applications.<br>
&gt; &gt;<br>
&gt; &gt; Just to clarify: are your libs using the interface or providing it?<br>
&gt;<br>
&gt; Providing it. My thinking on this is that rather than try and force people<br>
&gt; to implement a musicbrainz specific set of classes that will probably serve<br>
&gt; as nothing more than transfer points between the m/brainz service and the<br>
&gt; client app&#39;s own, more specialized, meta data class model my lib will \
just<br> &gt; provide a set of abstract interface classes that client apps can \
then<br> &gt; implement in what ever way makes most sense for them.<br>
&gt;<br>
&gt; The musicbrainz lib would then just have a bunch of functions that it<br>
&gt; performs against classes that implement the interface. The main operations<br>
&gt; would be creation and visiting combined with update / creation (for example<br>
&gt; when an existing local hierarchy is refreshed from the musicbrainz service,<br>
&gt; say when an artist releases a new album)<br>
<br>
</div>I don&#39;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.</blockquote><div><br>I think we might be having terminology issues \
:)<br><br>API wise, the lib provides what you&#39;d expect: look up artist by name, \
get album by CD ID that sort of thing. What I&#39;ve be going on about though is the \
set of abstract base classes I&#39;m knocking together that client code could inherit \
from to interact with the library. <br> <br>My thinking is, most client code is going \
to have an existing hierarchy of some form already to represent the typical \
MusicCollection-&gt;Artist-&gt;ReleaseCollection-&gt;Release-&gt;TrackCollection-&gt;Track \
hierarchy and it could be implemented with any number of possible back ends. For a \
situation like a CDDB or musicbrainz lookup of a CD etc there is not a lot of \
overhead in creating the quite small object hierarchy to represent a single release, \
but I think its a different story for an application like say a music manager \
application. Lets say this Mythical Music Manager provides a batch operation like \
trying to best guess identify all your badly labeled, possibly duplicated music files \
and which artist / album they belong to. If you&#39;ve already parsed the collection \
into a hierarchy, and lets say its a big collection, and then you&#39;ve walked that \
hierarchy and sent off a big bunch of queries to musicbrainz you would then end up \
with a second big hierarchy returned to you. Instead, if the MMM collection hierarchy \
through either interface classes or multiple inheritance supported it&#39;s own as \
well as the musicbrainz lib class models then the MMM collection would be passed to \
and updated by the musicbrainz lib query functions.<br> <br>I think I&#39;m doing a \
really bad job of explaining this :(<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>
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>
<div><div></div><div class="Wj3C7c"><br>
&gt; &gt; [If its the latter: Did you have a look at libkcddb (which has no<br>
&gt; &gt; maintainer<br>
&gt; &gt; AFAIK). Maybe you could build upon that?]<br>
&gt;<br>
&gt; Nope, haven&#39;t looked at the cddb lib, will do when I get home from work<br>
&gt; tonight.<br>
&gt;<br>
&gt; &gt; &gt; One thing that is getting me is when I try to come up with a way \
to<br> &gt; &gt; &gt; represent container classes for things like an artist&#39;s \
release<br> &gt; &gt;<br>
&gt; &gt; collection.<br>
&gt; &gt;<br>
&gt; &gt; &gt; In an effort to not force implementation decisions on clients, it \
would<br> &gt; &gt; &gt; seem that the way to go would be to specify a collection \
class that<br> &gt; &gt; &gt; provided accessors, iterators etc and allow the client \
to specify the<br> &gt; &gt; &gt; implementation (QList or what have you).<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; My other concern is how to represent the relationship between a \
higher<br> &gt; &gt; &gt; order class such as an artist and their release collection. \
Is it<br> &gt; &gt; &gt; enough<br>
&gt; &gt;<br>
&gt; &gt; to<br>
&gt; &gt;<br>
&gt; &gt; &gt; just specify in the artist interface that it return a reference to \
an<br> &gt; &gt; &gt; object implementing the releasecollection interface? This \
scares me a<br> &gt; &gt; &gt; bit as it means implementations will probably end up \
passing out<br> &gt; &gt; &gt; handles to member data structures. Is this a valid \
concern for an<br> &gt; &gt; &gt; interface designer or is that a problem that gets \
passed on to the<br> &gt; &gt; &gt; client code?<br>
&gt; &gt;<br>
&gt; &gt; I think the proper encapsulation cannot be enforced completely be the<br>
&gt; &gt; interface designer. One could still code a class that would expose<br>
&gt; &gt; members. QT4 tends to return shared copies of almost everything. This<br>
&gt; &gt; makes usage very<br>
&gt; &gt; easy and you don&#39;t have to care about exposing internal data \
members<br> &gt; &gt; since changes will return in a deep copy.<br>
&gt; &gt;<br>
&gt; &gt; More after clarifying the question above. ;)<br>
&gt;<br>
&gt; I guess the area that I&#39;m going back and forth on the most is how to \
model<br> &gt; the container classes in a way that doesn&#39;t force implementation \
decisions<br> &gt; on the client. If I define an interface that is essentially a \
subset of a<br> &gt; typical QList type container class with the basic accessors and \
modifiers<br> &gt; required for the lib to do it&#39;s job then clients can put \
regular<br> &gt; containers, databases or any other type of back end behind it, which \
is<br> &gt; what I&#39;m looking for.<br>
&gt;<br>
&gt; WRT encapsulation, my concern is that an interface class such as IArtist<br>
&gt; would have to offer non-const access to an object that implements the<br>
&gt; IReleaseList container, which in turn leads to exposing the IArtist<br>
&gt; implementation&#39;s internals. Is this a valid concern?<br>
<br>
</div></div>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>
&nbsp;IRelease release( int i ) const;<br>
&nbsp;IRelease&amp; release( int i );<br>
}<br>
<br>
Both allow to change a non-const Artist object while disallowing access to a<br>
const one. The second one is more along the lines of the QT4 way.<br>
<div><div></div><div class="Wj3C7c"><br>
Cheers,<br>
Sebastian</div></div></blockquote><div><br>Thanks Sebastian, I think that I was just \
over-thinking this issue!<br><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;"> <div><div class="Wj3C7c"><br>
<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