473,383 Members | 1,876 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

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 1606
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Omer van Kloeten | last post by:
The Top Level Design: The class Base is a factory class with a twist. It uses the Assembly/Type classes to extract all types that inherit from it and add them to the list of types that inherit...
4
by: eric | last post by:
Greetings, I am looking for C++ implementations of a pattern similar to the following description. This pattern is a wrapper of sorts (in the general sense, not like a Decorator) for a single...
11
by: FluffyCat | last post by:
In Febraury - April of 2002 I put together in Java examples of all 23 of the classic "Gang Of Four" design patterns for my website. Partly I wanted to get a better understanding of those patterns....
12
by: FluffyCat | last post by:
New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern Examples - the Visitor Pattern. In the Visitor pattern, one class calls a function in another class and passes an instance of...
22
by: Krivenok Dmitry | last post by:
Hello All! I am trying to implement my own Design Patterns Library. I have read the following documentation about Observer Pattern: 1) Design Patterns by GoF Classic description of Observer....
13
by: Alan Silver | last post by:
Hello, MSDN (amongst other places) is full of helpful advice on ways to do data access, but they all seem geared to wards enterprise applications. Maybe I'm in a minority, but I don't have those...
0
by: AMDRIT | last post by:
I am looking for better concrete examples, as I am a bit dense, on design patterns that facilitate my goals. I have been out to the code project, planet source code, and microsoft's patterns and...
13
by: Bilz | last post by:
Hello, I am looking for a good pattern. I have a rather large software app that makes use of a service manager for its many services... configuration, colors, data lookup, units, etc. Up until...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.