Software Design
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming Languages - MoreSoftware Design

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old April 11th, 2007, 09:44 PM
jtxx000 jtxx000 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2007
Posts: 2 jtxx000 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 11 m 37 sec
Reputation Power: 0
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

Reply With Quote
  #2  
Old April 12th, 2007, 03:15 AM
Hugh of Borg's Avatar
Hugh of Borg Hugh of Borg is offline
Contributing User
Dev Shed Novice (500 - 999 posts)
 
Join Date: Jun 2004
Location: Switzerland
Posts: 926 Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level)Hugh of Borg User rank is Lieutenant General (80000 - 90000 Reputation Level) 
Time spent in forums: 1 Week 5 Days 3 h 9 m 41 sec
Reputation Power: 855
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!

Reply With Quote
  #3  
Old April 15th, 2007, 02:29 PM
jtxx000 jtxx000 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2007
Posts: 2 jtxx000 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 11 m 37 sec
Reputation Power: 0
That sounds like it will work. Thanks.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - MoreSoftware Design > Composite Pattern Fun


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump




 Free IT White Papers!
 
How to Present Effectively Online
This white paper offers practical and actionable advice on the key steps that any presenter should consider as they plan and execute a Webinar or online meeting.

 
Open Source Security Myths
Open Source Software (OSS) is computer software whose source code is available to the general public with relaxed or non-existent intellectual property restrictions (or arrangement such as the public domain), and is usually developed with the input of many contributors.

 
Power and Cooling Capacity Management for Data Centers
This paper describes the principles for achieving power and cooling capacity management.

 
Scalable, Fault-Tolerant NAS for Oracle - The Next Generation
For several years NAS has been evolving as a storage alternative for Oracle databases, and for good reason: NAS is quite often the simplest, most cost-effective storage approach for Oracle. Learn about the benefits that HP's approach to scalable NAS brings to Oracle environments in this comprehensive white paper.

 
Understanding Web Application Security Challenges
This white paper discusses many common threats and preventive measures for Web application security, and explains what you can do to help protect your organization.

 

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 




© 2003-2010 by Developer Shed. All rights reserved. DS Cluster 1 Hosted by Hostway
For more Enterprise Application Development news, visit eWeek