| | | ma740988 |  |
| Posted: Sat Aug 23, 2008 11:58 pm Post subject: observer / mediator perhaps ... design woes |  |
| |  | |
Referencing the source below, I have a platform, a controller and up to four pumps max. Platform communicate with pumps via controller and vice versa. For platform->(to)pump communication, I believe the observer design pattern would suffice. For the reverse[ pump->(to)platform ] I'm confused on a design choice although I believe some combination of observer and mediator will suffice.
Coupled with my design woes, I've got a couple issues: a) Within the HandleMessage method in the Platform class, how could I make the Notify function generic such that the message type (PlatformMsg_1M or PlatformMsg_2M) is independent? NOTE: From platform-
| Quote: | (to)pump a PlatformMsg_1M or PlatformMsg_2M message is sent.
|
b) I suspect I need a pumpHandler class. A pointer to this pump handler class could be in the Controller class. How could I structure the code such that when I send a message from pump->(to)platform the platform is notified of the appropriate message? NOTE: From pump-
| Quote: | (to)platform a PumpMsg_1M or PumpMsg_2M message is sent.
|
I tend to struggle in the design arena so I'm open to restructure/ redesign considerations.
Thanks in advance.
//code # include <iostream> # include <vector>
enum MSG_TYPE { _1M, _2M };
// Event delegate interface class struct EventHandlerDelegate { typedef void ( EventHandlerDelegate::*handler_fp )( int ); virtual void handle( int ) = 0; virtual ~EventHandlerDelegate(){} };
/* ---------------------------------------------------------------------------- ------------ | Our pumps.. (Pump_1, Pump_2, Pump_3 or Pump_4 ). | We could instantiate all 4 or any number of pumps ---------------------------------------------------------------------------- ------------ */ class PumpMsg_1M { int hdr; public : void setHeader ( MSG_TYPE msg ) { hdr = msg ; } int getHeader ( MSG_TYPE msg ) const { return ( hdr ) ; } }; class PumpMsg_2M { int hdr; public : void setHeader ( MSG_TYPE msg ) { hdr = msg ; } int getHeader ( MSG_TYPE msg ) const { return ( hdr ) ; } };
// Pump_1 event handler struct Pump_1 : EventHandlerDelegate { void handle( int e ) { std::cout << " Pump_1 notified " << e << std::endl; } }; // Pump_2 event handler struct Pump_2 : EventHandlerDelegate { void handle( int e ) { std::cout << " Pump_2 notified " << e << std::endl; } }; // Pump_3 event handler struct Pump_3 : EventHandlerDelegate { void handle( int e ) { std::cout << " Pump_3 notified " << e << std::endl; } }; // Pump_4 event handler struct Pump_4 : EventHandlerDelegate { void handle( int e ) { std::cout << " Pump_4 notified " << e << std::endl; } };
// Our functor template < typename classT, typename memfuncT > class functor { memfuncT memfunc_; classT * class_; public: functor() : class_ ( 0 ) , memfunc_( 0 ) {}
functor(classT * c, memfuncT f) : class_( c ) , memfunc_( f ) {}
void operator()( int e ) { if( class_ && memfunc_ ) { (class_->*memfunc_)( e ); } } ~functor() { delete class_; } };
// Friendly typedef of our functor for this specific usage typedef functor<EventHandlerDelegate, EventHandlerDelegate::handler_fp> EventHandlerFunctor;
/* ---------------------------------------------------------------------------- ------------ | Platfom class .. used to notify the pumps (Pump_1, Pump_2, Pump_3 or Pump_4 ) ---------------------------------------------------------------------------- ------------ */ class PlatformMsg_1M { int hdr; public : void setHeader ( MSG_TYPE msg ) { hdr = msg ; } int getHeader ( MSG_TYPE msg ) const { return ( hdr ) ; } }; class PlatformMsg_2M { int hdr; public : void setHeader ( MSG_TYPE msg ) { hdr = msg ; } int getHeader ( MSG_TYPE msg ) const { return ( hdr ) ; } };
class Platform {
typedef std::vector<EventHandlerFunctor *> handler_t; typedef handler_t::const_iterator hciter; typedef handler_t::iterator iter; handler_t handler_;
PlatformMsg_1M msg1M; PlatformMsg_2M msg2M; // Extract handler from map and call polymorphic handle() function // Gets called in the context of the base class but dynamic binding ensures // the handler for the correct delegate class is called. void Notify( int e ) { for( hciter itr = handler_.begin() ; itr != handler_.end() ; + +itr) { EventHandlerFunctor * func = (*itr); (*func)( e ); } }
public: // Log events and handlers in a map void Attach(EventHandlerFunctor * func) { handler_.push_back(func); } void HandleMessage ( MSG_TYPE e ) { if ( e == _1M ) { msg1M.setHeader ( e ) ; //Notify ( PlatformMsg_1M ); } else if ( e == _2M ) { msg2M.setHeader ( e ) ; //Notify ( PlatformMsg_2M ); } else {} } // Clear up the handlers ~Platform() { for( hciter itr = handler_.begin() ; itr != handler_.end() ; + +itr ) { delete *itr; } } };
/* ---------------------------------------------------------------------------- ------------ | Controller class .. ---------------------------------------------------------------------------- ------------ */ // Controller class class Controller { Platform *ptr_platform;
public: Controller () : ptr_platform ( new Platform() ) {}
// the create function will have more intelligence..not all pumps may be attached.. void Create () { ptr_platform ->Attach ( new EventHandlerFunctor ( new Pump_1, &EventHandlerDelegate::handle ) ); ptr_platform-> Attach ( new EventHandlerFunctor( new Pump_2, &EventHandlerDelegate::handle ) ); } /* | Test functions.. | a) Send platform message (platform->pump) | b) Send pump message ( pump->platform ) */ void send_platform_message ( MSG_TYPE msg ) { ptr_platform->HandleMessage ( msg ) ; } void send_pump_message ( MSG_TYPE msg ) { //Need a pump manager } ~Controller () { delete ptr_platform ; }
};
int main() { Controller ct; ct.Create() ; ct.send_platform_message ( _1M ) ; }
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|