Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++

observer / mediator perhaps ... design woes

 
Jump to:  
 
ma740988
PostPosted: 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! ]
 

Page 1 of 1 .:.

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

pasy ciążowe montaż drzwi Warszawa idol Dynamika maszyn elektrycznych prądu przemiennego Wierszyki noworoczne