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
|
|
0
|
|
|
|
Reply
|
ebasconp (57)
|
10/31/2006 2:26:20 AM |
|
Ernesto Basc�n wrote:
> 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.
--
Phlip
http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
|
|
0
|
|
|
|
Reply
|
phlipcpp (2479)
|
10/31/2006 4:17:57 AM
|
|
Phlip wrote:
> Ernesto Basc=F3n wrote:
>
> > 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.
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
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
10/31/2006 8:23:30 AM
|
|
Ernesto Basc=F3n wrote:
> 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 =3D 0>
struct Discern
{
};
template <class RetT, int descrim =3D0>
struct ViewIfToModel
{
virtual RetT get( const Discern<RetT, descrim>& ) const =3D 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 ) =3D 0;
virtual void set( const T& data ) =3D 0;
protected:
~CtrlIfToModel(){ ; }
};
//...And
template <class T, int discrim =3D 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
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
10/31/2006 8:48:11 AM
|
|
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
|
|
0
|
|
|
|
Reply
|
ebasconp (57)
|
10/31/2006 12:41:15 PM
|
|
Ernesto Basc=F3n wrote:
> 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()=3D 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() =3D 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() =3D 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
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
10/31/2006 3:36:52 PM
|
|
werasm wrote:
> Phlip wrote:
> > Ernesto Basc=F3n wrote:
> >
> > > 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 a=
re
> > 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.
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.
|
|
0
|
|
|
|
Reply
|
bart.kowalski (190)
|
10/31/2006 9:25:30 PM
|
|
Bart wrote:
> 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
>
> Regards,
> Bart.
|
|
0
|
|
|
|
Reply
|
w_erasm (159)
|
11/1/2006 7:13:32 AM
|
|
|
7 Replies
23 Views
(page loaded in 0.207 seconds)
Similiar Articles: where is the ImageDisplay class and javax.media.* package? - comp ...JMF 2.0 API (03/10/01): Package javax.media Package javax.media ... Controls provides an interface for obtaining objects by interface or class name. Enum type inside a class (matlab <-> java interface) - comp.soft ...Hello, Let's say I want to define this in java : package internet; public class Downloader { public enum DownloadStatus { INITIALIZING, IN_P... Get rid of unused parameter warning? FollowI have an abstract base class which defines an interface to a function which takes 3 arguments. From that ABC I define a set of derived classes whi... Multiple Routes + Multiple Interfaces to the same Router/Gateway ...... Solaris handle a situation like follows: default ->router1 IP-A -> router1->Interface-A IP-B -> router1 -> interface-B IP-C -> router1 ->interface-C all IPs are Class ... How redirect event between two public class? - comp.lang.java.gui ...JScrollPane does not show up - comp.lang.java.gui Cheers, //mikael public class Exercise2View extends JFrame ... when this observer is notified (Observer interface) public ... nitializing a static vector <> of integers (this static vectorWhat you can do is to wrap the container into an interface (class, or bunch of functions) that controls the number of elements. > //As before > class SignalHandler ... NetBeans jList Add/Clear Items - comp.lang.java.guiinit: deps-jar: Compiling 1 source file to C:\Reports\Jeff\java\StudyX\build\classes ... AddQuestions.java:27: cannot find symbol symbol : method clear() location: interface ... GUI Object Design - comp.lang.java.guiYou can *build* your user interface, either with builder classes or builder methods. For example you can use methods like #buildFrame, #buildMenuBar, #buildFileMenu ... Worker Threads and EDT - comp.lang.java.gui... not a specific worker thread will cause problems because dependencies back to the UI are typically routed through at least one interface, one or more abstract classes ... Need help on Java server configuration - comp.sys.tandem ...... that discusses the Java Native Interface, but it is unclear to me whether that environment variable is intended for finding HP-supplied Java Native Interface classes or ... interface vs abstract class : Java GlossaryCanadian Mind Products Java & Internet Glossary : interface vs abstract class What Is an Interface? (The Java™ Tutorials > Learning the Java ...If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile. 7/16/2012 5:05:26 AM
|