The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

This may be a stupid question

I’ve got a C++ class that represents a custom GUI control and this control has a lot of user-changeable styles. Rather than have the instance creator have to pass the constructor an obnoxious number of arguments, or have them do an obnoxious amount of function calls to set all of the properties, is it acceptable – and more importantly proper – to create a structure in the header file, have them create an instance of the structure, fill in all of the style variables and pass the address of the structure to the class constructor?
AverageMidget Send private email
Thursday, November 01, 2007
I can't see any reason for not letting them set options in a struct. However I would have thought the control would start with a default set of options and the user would overide any specific ones they wanted to. Having to spec all options in a struct or the CTor just so I can change a few is PITA.
Neville Franks Send private email
Thursday, November 01, 2007
I don't understand what a structure will get you. You have to set all the parameters - be it in the structure which you pass to the class or the constructor of the class or an init function or setter functions.

Since there are so many attributes, you might want to think about breaking down the class into smaller classes.

Think about maintenance. Do what will be easy to maintain - you will spend 90% of your time doing it.
Friday, November 02, 2007
Well, as it stands now, I have the constructor set most of the member variables to default settings. I know it's roughly the same amount of work to pass everything to the constructor as it is to fill in a structure and pass it to the constructor, I was just thinking it looked cleaner, from a code stand-point. Maybe I'm just over-thinking things.
AverageMidget Send private email
Friday, November 02, 2007
Yep, some people call this the parameter object idiom. Its quite nice, especially when not all settings are manditory. If the number of manditory fields is high, I add a validate() method that the accepting class calls. I also often use the method chaining idiom for the setters, which makes it look a tad cleaner. You'll sometimes see a slight varient called an execution context that serves the same purpose.
Benjamin Manes Send private email
Friday, November 02, 2007
Depends on what you mean by "style".

If your "style" is purely about visual characteristics (i.e. GUI skinning), and not functional characteristics, put it in a separate class (with suitable defaults), so you can share it with other instances of the control, or even other controls.

For stuff that's functionally different (which most of the time will be different even between instances of the same control), just put it in the control instance.

Friday, November 02, 2007
> is it acceptable – and more importantly proper

I like it a lot. It's especially useful when there's some indirection, like ...

class Facade
  static Foo* createFoo(const FooOptions& fooOptions)
    return new Foo(fooOptions);

... or when it's a virtual function that's declared in more than one class, because then you can change the definition of the FooOptions struct without editing the intermediate (factory and/or interface) classes.
Christopher Wells Send private email
Friday, November 02, 2007
I would create a singleton "StyleController" class, that holds a repository of styles, these can be stored in some xml files.

Your UI classes adopt a "StyleHelper" class/interface, deriving a class for each UI Widget that has some different properties. These listen for messages from the StyleController.

This lets you:

1. Separate the styling functions from your UI class, and

2. Have the ability to broadcast style changes to all UI instances that support the StyleHelper interface.

Consider that if you need to change your UI toolkit to something that doesn't support your styling in the same way, you aren't tied to your specific styling logic, having to strip it all out. You could reasonably adapt your styling and helper classes to a new library.
Jason T
Friday, November 02, 2007
I quite like this pattern.

The alternative is a new class with a full set of 'getters' and 'setters', each of which has to be called separately.

Creating a 'struct' and passing references around can be quite concise.
Friday, November 02, 2007
We do the same here.
Only difference is that we have our object (class Style) as a property that gets set at runtime.
This is only because we are embedded thus we re-use windows forms (cause Windows handles are so damn expensive), so 1 control might have many styles applied to it over the apps lifecycle.

It works well.
Jax Send private email
Saturday, November 03, 2007
When dealing with a relatively large set of parameters I usually automate creating of a class that sets/gets them.

In your case I would have a separate class with generated member and set/get methods list, also a copy constructor and assignment operator.

Input for such class is a simple text file with the list of parameters. My (python) script would read it generate the class etc all in a consistent naming manner.

Then the class gets committed under a source control.

Advantage that when you need to add/remove/edit a parameter you simply change the input text file and run the script to regenerate the class. Also as a perk you get default values for your parameters.

Also if your methods naming convention is logical you can code without looking at that class header file.
deem Send private email
Monday, November 05, 2007
+1 Christopher Wells  on the Facade

Another option (Depending on the object and interface) is the "Decorator Pattern".

Tuesday, November 06, 2007

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
Powered by FogBugz