469,927 Members | 1,832 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,927 developers. It's quick & easy.

Looking for a design pattern

Hi,

I just know there must be some kind of well-known design pattern here, but
I'll be damned if I can find it...

Let me explain my situation.

I have a hierarchy of classes for a GUI. All derived from class 'Primitive'.
Fine so far.

I want to add styled 'themes' to my framework so objects will be drawn to
look the same for a certain theme. In doing this, I free up the
responsibility of the base classes in knowing how to draw themselves (they
still do other stuff like event handling, etc.), so I can reuse the classes
in other applications, but have them drawn differently.

I'm just stuck trying to come up with the best way to do this.

My solution at the moment (but I'm still not happy with it) is:

Primitive::Draw forwards drawing responsibility to
GetCurrentTheme()->DrawObject( this, GetRect() ).

Because the Theme object doesn't know what derived Primitive is being drawn
at this point, it has to dynamic_cast the base class pointer to find out
what type of object is really being drawn, and draw that particular type of
object.

The thinking behind this was that a 'default' theme could cope with drawing
the most basic primitives - buttons, check boxes, etc. in a default style.
If it gets a primitive it doesn't know about, it draws nothing.

As the framework is extended new types of primitive are added, and, in
particular, specific applications may use their own primitives.

So, as the types of primitive are extended, so too are themes to cope with
drawing them.

It just feels awkward having to use dynamic_cast to work out exactly what
type of object will be drawn, and I can't help but think there must be some
other way to do this.
TIA for any advice. I'll be happy explain more if required.

--
Cheers,
Steve.

Jul 23 '05 #1
3 1461
Steve wrote:
My solution at the moment (but I'm still not happy with it) is:

Primitive::Draw forwards drawing responsibility to
GetCurrentTheme()->DrawObject( this, GetRect() ).

Because the Theme object doesn't know what derived Primitive is being drawn at this point, it has to dynamic_cast the base class pointer to find out
what type of object is really being drawn, and draw that particular type of object.


You are asking for "double dispatch". The DrawObject should dispatch based
on both the types of the theme and the primitive. This is the Visitor
Pattern.

However, your concern for getting this design "right" might betray your
concern that you can't change these classes, after they work right, to
retrofit a pattern. And that concern might lead you to "overdesign" the
situation. If your themes are very similar, for example, you could need
"less" of a pattern. But if you commit to such code, and its requirements
change in the future, you might fear that you will then need to hack the
design, or change the design and risk bugs. So the fear will drive you to
overdesign now, rather than debug later.

Read /Refactoring to Patterns/. It will recommend that all features (even
GUI features) come with a complete suite of unit tests. If you have them,
you can refactor in tiny bits, and expect all the tests to pass between each
bit. This technique makes bugs very rare, because if the tests fail you can
use Undo and try again. A failing test indicates you forgot something in
your latest edit, so you can't procede until you remember it.

To write unit tests for GUIs, start with this checklist:

http://www.c2.com/cgi/wiki?TestFirst...acesPrinciples

Then, generally, Google for:

GUI phlip reveal

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand
Jul 23 '05 #2
Steve wrote:
I just know there must be some kind of well-known design pattern
here, but I'll be damned if I can find it...
Adapter, Proxy, Bridge. Depends on how you choose to implement
it in your particular solution.

Also, your objects that don't know how to draw themselves in terms
of the display, but do know how to draw them in terms of some kind
of elements they consist of (border, face, text, etc.), are basically
composites. Your Theme should provide the necessary "callbacks" or
"tools" from a "kit" that would do the drawing of those elements.
Every "Primitive" (which now is a composite of "elements") will then
call Theme's methods to represent themselves in terms of that Theme.
I am not sure under what pattern this falls. Double dispatch?
[...]


V
Jul 23 '05 #3
ben
1) Figure out what can be drawn completely without current theme;
2) Figure out what can be drawn with little information from current theme
(background color, foreground color, etc)
3) Figure out what must be drawn by the theme (rounded cornor, transparency,
etc)
Hi,

I just know there must be some kind of well-known design pattern here, but
I'll be damned if I can find it...

Let me explain my situation.

I have a hierarchy of classes for a GUI. All derived from class 'Primitive'. Fine so far.

I want to add styled 'themes' to my framework so objects will be drawn to
look the same for a certain theme. In doing this, I free up the
responsibility of the base classes in knowing how to draw themselves (they
still do other stuff like event handling, etc.), so I can reuse the classes in other applications, but have them drawn differently.

I'm just stuck trying to come up with the best way to do this.

My solution at the moment (but I'm still not happy with it) is:

Primitive::Draw forwards drawing responsibility to
GetCurrentTheme()->DrawObject( this, GetRect() ).

Because the Theme object doesn't know what derived Primitive is being drawn at this point, it has to dynamic_cast the base class pointer to find out
what type of object is really being drawn, and draw that particular type of object.

The thinking behind this was that a 'default' theme could cope with drawing the most basic primitives - buttons, check boxes, etc. in a default style.
If it gets a primitive it doesn't know about, it draws nothing.

As the framework is extended new types of primitive are added, and, in
particular, specific applications may use their own primitives.

So, as the types of primitive are extended, so too are themes to cope with
drawing them.

It just feels awkward having to use dynamic_cast to work out exactly what
type of object will be drawn, and I can't help but think there must be some other way to do this.
TIA for any advice. I'll be happy explain more if required.

--
Cheers,
Steve.

Jul 23 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Omer van Kloeten | last post: by
12 posts views Thread by FluffyCat | last post: by
22 posts views Thread by Krivenok Dmitry | last post: by
13 posts views Thread by Bilz | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.