[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-21 18:53:35
Message-ID: 92af7fc70807211153x2c6f5f46t94a02348295866b () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Mon, Jul 21, 2008 at 7:37 AM, Sebastian Tr=FCg <trueg@k3b.org> wrote:

> On Saturday 19 July 2008 00:50:32 Nathan Bradshaw wrote:
> > 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 KD=
E
> > > > > > musicbrainz lib I've been building is to replace my local
> > > > > > album/release/track classes with a set of interface classes tha=
t
> > >
> > > actual
> > >
> > > > > > real software (rather than my toy test progs) can implement
> > > > > > alongside whatever their native representation of music metadat=
a
> > > > > > 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 i=
t?
> > > >
> > > > Providing it. My thinking on this is that rather than try and force
> > >
> > > people
> > >
> > > > to implement a musicbrainz specific set of classes that will probab=
ly
> > >
> > > serve
> > >
> > > > as nothing more than transfer points between the m/brainz service a=
nd
> > > > the client app's own, more specialized, meta data class model my li=
b
> > > > will
> > >
> > > just
> > >
> > > > provide a set of abstract interface classes that client apps can th=
en
> > > > 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.
> >
> > I think we might be having terminology issues :)
> >
> > API wise, the lib provides what you'd expect: look up artist by name, g=
et
> > album by CD ID that sort of thing. What I've be going on about though i=
s
> > the 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->Tra=
ck
> > 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 the=
re
> > is not a lot of overhead in creating the quite small object hierarchy t=
o
> > represent a single release, but I think its a different story for an
> > application like say a music manager application. Lets say this Mythica=
l
> > Music Manager provides a batch operation like trying to best guess
> identify
> > all your badly labeled, possibly duplicated music files and which artis=
t
> /
> > 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 th=
at
> > 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's own as well as the musicbrainz lib class
> models
> > then the MMM collection would be passed to and updated by the musicbrai=
nz
> > lib query functions.
>
> So you want clients to use your lib implicately by inheriting from its
> classes
> to allow internal updating. Example:


Yup, thats correct.


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