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

List:       kde-devel
Subject:    Re: OO design help
From:       Sebastian =?utf-8?q?Tr=C3=BCg?= <trueg () k3b ! org>
Date:       2008-07-21 11:37:27
Message-ID: 200807211337.27536.trueg () k3b ! org
[Download RAW message or body]

On Saturday 19 July 2008 00:50:32 Nathan Bradshaw wrote:
> On Fri, Jul 18, 2008 at 3:44 AM, Sebastian Trüg <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ü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.
>
> 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
> 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->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'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 supported it'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.

So you want clients to use your lib implicately by inheriting from its classes 
to allow internal updating. Example:

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 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.
> >
> > 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 <<

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

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