|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| ||||||||||||||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Composite Pattern Fun
Greetings all,
I am trying to create a hierarchic data structure that contains a virtual/abstract process() method. Subclasses may or may not contain children and override the process method to provide functionality. Seems simple enough right? Here's the catch: if a node has children, then process() must be called for each of its children before it can do any processing itself. So the simplest design I can think of would be to have a single Module class that would hold one or more child Modules, and have child classes explicitly call process() on the parent: Code:
class Module {
private:
Array<Module> children;
public:
virtual void process() {
for (int i=0; i<children.size(); i++) {
children[i]->process();
}
}
};
class MyModule {
public:
virtual void process() {
Module::process();
//do processing here
}
};
There are two problems with this approach. Firstly, Modules that don't contain any children have an unnecessary empty array. Secondly, all subclasses must remember to call Module::process(), or it doesn't work. Another approach would be to use the composite pattern and also have two separate process methods: Code:
class Module {
public:
virtual void process() {
doProcess();
}
virtual void doProcess()=0;
};
class CompositeModule : public Module {
private:
Array<Module> children;
public:
virtual void process() {
for (int i=0; i<children.size(); i++) {
children[i]->process();
}
doProcess();
}
};
class MyModule : public CompositeModule {
public:
virtual void doProcess() {
//do processing here
}
};
This has the benefit of not wasting space on an empty array for leaf Module--if there are no children then just inherit from Module instead of CompositeModule. It also removes the need for subclasses to call Module::process(). However, due to having two process methods there is now a wasted call for Modules without children. It's also not quite as elegant as the previous approach. Of course it would be possible to only have the doProcess() method for CompositeModules, but this is confusing for developers subclassing Module. If inheriting from CompositeModule then doProcess() needs to be overridden; if inheriting from Module then process() needs to be overridden. Any advice on what to do and/or why one method is better than the others? Is there a better way of doing this? Cheers, Caleb |
|
#2
|
||||
|
||||
|
I would create 2 abstract base classes. One for Modules that can't contain any child Modules and one Modules that can.
Then instead of having only one method 'process' add another one called 'callProcess' or something like that and make 'process' private. Template method pattern Code:
abstract class LeafModule
{
public callProcess()
{
this.process();
}
private abstract process();
}
abstract class ContainerModule : LeafModule
{
Array <LeafModule> modules;
public final callProcess()
{
foreach (LeafModule m in modules)
{
m.callProcess();
}
this.process();
}
private abstract process();
}
It could probably still use some improvement but it should fit most of your needs. Hope it gives you some new ideas.
__________________
- Hugh of Borg The first thing young borg are taught: Keep away from Microsoft software! |
|
#3
|
|||
|
|||
|
That sounds like it will work. Thanks.
|
![]() |
| Viewing: Dev Shed Forums > Programming Languages - More > Software Design > Composite Pattern Fun |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|