473,769 Members | 7,320 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 1631
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
3151
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 from it. During run time, using a static method, the class creates an instance of the derived class using the Activator class and returns it. This design pattern is very similar to the design pattern applied by the Assembly class. The twist is...
4
1339
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 arithmetic value. In the base class of this pattern, instances can be multiplied, added, compared, copied, and generally treated just like any other arithmetic value EXCEPT that the value of such instances cannot be directly assigned nor...
11
4309
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. They are still online at http://www.fluffycat.com/java/patterns.html Since September 2003 I've mainly been using PHP, and now that PHP 5 is becoming more available I am going to try the same thing I did in Java with PHP.
12
3039
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 itself. The called class has special functions for each class that can call it. With the visitor pattern, the calling class can have new operations added without being changed itself.
22
4744
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. Also describes implementation via ChangeManager (Mediator + Singleton) 2) Pattern hatching by John Vlissides Describes Observer's implementation via Visitor Design Pattern. 3) Design Patterns Explained by Alan Shalloway and James Trott
13
3114
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 sorts of clients. Mine are all small businesses whose sites will never reach those sorts of scales. I deal with businesses whose sites get maybe a few hundred visitors per day (some not even that much) and get no more than ten orders per day....
0
1997
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 practices site and it just isn't sinking in all that clearly to me. Currently we have code in production and it all works well, however it is not the way we want it. We know that we can implement a better design plan to improve performance,...
13
1364
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 now the service manager has been a singleton and anyone who wants access to a service just asks the singleton. Now we have a new requirement... run multiple instances of the software in the same application space with different configurations.
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8873
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7413
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5309
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3965
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.