Interface classes

  • Thread starter =?iso-8859-1?q?Ernesto_Basc=F3n?=
  • Start date
?

=?iso-8859-1?q?Ernesto_Basc=F3n?=

Opinions.

I want to create an OO UI framework.

I want to define a set of ABCs like:

class IA
{
virtual int GetA() = 0;
};

class IB : public IA
{
virtual double GetB() = 0;
};

class IC : public IA, public virtual IB
{
virtual char GetC() = 0;
};

After that, I want to create a set of implementation for my ABCs:

class A : public IA
{
virtual int GetA() { return 1;}
};

class B : public A, public virtual IB
{
virtual double GetB() { return 0.5; }
};

class C : public A, public B, public virtual IC
{
virtual char GetC() { return 'h'; }
};

The rational behind this is to provide the interfaces totally separated
from the implementation (providing different headers and implemented in
another shared library), adding this and working just with the
interfaces and with factory methods, I will be able to create instances
of my implementation or of third party implementations and if my
implementation mirrors the same class hierarchy than the ABCs, I will
be able to reuse the code already implemented in the base concrete
classes.

Do you consider my design as good? Do you think I should consider some
issues?
Do you think it is not a good design or that it could be improved?

Any comment will be very important to me.


Ernesto
 
P

Phlip

Ernesto said:
Do you think it is not a good design or that it could be improved?

Study "Model View Controller".

Next, C++ is very hard for GUIs, and is generally not indicated. GUIs are
command-and-control code, not system code, and they must respond in
user-time, not real-time. So you should start with a very soft language,
with duck-typing.
 
W

werasm

Phlip said:
Study "Model View Controller".

Next, C++ is very hard for GUIs, and is generally not indicated. GUIs are
command-and-control code, not system code, and they must respond in
user-time, not real-time. So you should start with a very soft language,
with duck-typing.

One could implement the MVC very elegantly in C++, given the power of
templates. I think with much less work as well. I don't see what makes
C++ so hard for GUI 's.

Regards,

Werner
 
W

werasm

Ernesto said:
Opinions.
Do you consider my design as good? Do you think I should consider some
issues?

I would rather templatise the get. As you can't overload on return type
and have many virtuals due to the possibility of ambiguities, you have
used different names. This does not scale well.

For this type of problem I would use the type that needs to be viewed
to discern between my virtual calls. Something like:

template<class T, int descrim = 0>
struct Discern
{
};

template <class RetT, int descrim =0>
struct ViewIfToModel
{
virtual RetT get( const Discern<RetT, descrim>& ) const = 0;

protected:
~ViewIfToModel(){}
};

Perhaps create similar kind interface thing from the controllers
perpective, and you could even use MI to create a joint interface that
allows setting and getting of data. I can't exactly remember the jargon
used for the controller, its either update or set...

template <class ArgT>
struct CtrlIfToModel
{
virtual void update( const T& data ) = 0;
virtual void set( const T& data ) = 0;
protected:
~CtrlIfToModel(){ ; }
};

//...And

template <class T, int discrim = 0>
struct AbstractSimpleModel : ViewIfToModel<T, discrim>,
CtrlIfToModel<T>
{
//etc... perhaps
};

//and SimpleModel, which has minimal implementation, perhaps..., and is
an abstractModel

Now,

struct ComplexModel :
SimpleModel<X>, SimpleModel<Y>, SimpleModel<Z>,
SimpleModel<Z,1>, SimpleModel<Z, 2>
{
};

Note: I'm just indicating more possibilities, they may have problems.
For instance, there are reasons why one may need to discriminate (when
having many copies of the same data for a reason - which copy do you
want to get/set). This is rare, though, and can be handled by some form
of adaptation as afterthought, instead of including the discrimination
as I have done here.

I slapped it together quite fast, hope I'm not missing something -
gurus?

Regards,

Werner
 
?

=?iso-8859-1?q?Ernesto_Basc=F3n?=

HI Werner:

Actually my example shows several methods that must be implemented in
the implementation classes; maybe this example is clearer:

class IControl
{
virtual string GetName()= 0;
};

class IButton : public IControl
{
virtual void PerformClick() = 0;
};

Do you consider a good design to provide implementation classes like:


class Control : public IControl
{
virtual string GetName() { return "name"; }
};

class Button : public Control : public virtual IButton
{
virtual void PerformClick() { ... }
};


and factory methods for all the classes? Any consideration I could take
into account?

thanks in advance,



ernesto
 
W

werasm

Ernesto said:
HI Werner:

Actually my example shows several methods that must be implemented in
the implementation classes; maybe this example is clearer:

class IControl
{
virtual string GetName()= 0;
};

Depending on whether name is class specific or instance specific, I
would either, when implementing, have a const static member or a const
member. I think it is not to strict to have GetName return string by
reference. I'm assuming you do specify whether deletion would be viable
via these interfaces... by either making your destructor protected or
virtual and public.
class IButton : public IControl
{
virtual void PerformClick() = 0;
};

Well, hard call, but IMO your interface is too concise. How about:

struct NamedObject
{
virtual std::string& getName() const{ return unnamed_; }
virtual ~NamedObject(){}
private:
static std::string unnamed_( "Not Specified" ); //supply def!
};

struct Cmd
{
virtual void execute() = 0;
};

The command pattern is very implementable in C++ (and its been done for
you - see boost::function, boost::signal or Loki). Usually controls
like buttons interface with a command (Button has a command). C++
Builder had this concept (they called it closures). The QT frameworks
has it, and C# has thought of some fancy name for it called delegates.
Do you consider a good design to provide implementation classes like:

Sometimes, yes, others, not. Typically when you have "Don't call me,
I'll call you bases" - "template method", then yes, implementation may
exist in the base class. When my base requires to have protected
members, I become worried, though. In general I would only implement
the getting of the name in the most derived, and I would not do it the
way you did it.

Also, rtti provides you with a compiler generated name (on class
level). Most often this is fairly concise. If name is something that is
required on instance level - like person.name, then I would consider
it, yes. If name is a constant member, you may as well make it public -
no harm (IMO). This is quite strict, as it does make NamedObject
non-copyable.

struct NamedObject
{
//For anybody as non-modifiable anyway
const std::string name_;

NamedObject( const std::string& name ): name_( name ){}
};

Now its not an interface anymore, and virtual inheritance becomes a
requirement when using MI (to share data), which can be a drawback. You
would get the same kind of ambiguities when using MI. The point is, I
don't consider this less encapsulating than having getName, for
instance (mostly because of its constness).
and factory methods for all the classes? Any consideration I could take
into account?

Well, depends... I personally rarely use factory methods. I often use
cloning (prototyping). I have a little idiom that allows a class to
take ownership of a base type (Almost like an abstract factory with a
concise interface for a single object). The object (base) to be created
is templatized and the concrete factory implementation is open.

Something like:

template <class T>
CreationIF
{
virtual T* create() const;

protected:
~CreationIF(){ }
};

//Client is interested in owning SomeBase...
Client::Client( const CreationIF<SomeBase>& baseFactory )
: myBase_( baseFactory.create() )
{
}

You pick how you decide to implement CreationIF<T>. The client gets to
specify who he wants to own...

Regards,

Werner
 
B

Bart

werasm said:
One could implement the MVC very elegantly in C++, given the power of
templates. I think with much less work as well. I don't see what makes
C++ so hard for GUI 's.

I know it's rather hard to convince C++ programmers of the merits of
dynamic ("duck-typed" as Phlip put it so well) languages. However, I
encourage you to look into, say, Smalltalk or Python. It may open your
mind.

Regards,
Bart.
 
W

werasm

Bart said:
I know it's rather hard to convince C++ programmers of the merits of
dynamic ("duck-typed" as Phlip put it so well) languages. However, I
encourage you to look into, say, Smalltalk or Python. It may open your
mind.

I might do so. I have (attempted) in the past to implemented an
(almost) pure MVC type system, where I split my functional requirements
from my graphical requirements totally. I could for that system with
minimal programming convert to another OS, and use a totally different
graphic library as well. The graphics started out using a console.

Nowadays though, for our graphics we use QT, and our processing side
(or system side) reside on another processor. We still use an MVC like
architecture, where our graphics are considered the controls and the
views. Commands (taking up to five arguments) with the ability to
execute any callback cross-thread help us to a large extent wrt. the
control part.

I will check out duck typing though. I may be wrong, but the ability of
function templates to derive the type from the argument seems similar
in concept (this is from a control perpective). Nevertheless, I cannot
really comment, probably due to my narrow mind :). My point just
remains, implementing MVC in C++ is possible. I think I must check out
Python though, you not the first that has told me about it.

Regards,

Werner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top