Re: Generic message holder class design
On Jan 7, 1:13 pm, ?? Tiib <oot...@hot.ee> wrote:
[...]
Considered ... i did not spot indication in the snippet where you try
to receive, handle and respond your messages. Also the comments did
not answer to question "why?" (it is single question that is worth
answering in comments).
You?re correct in that I tried to post the minimal amount of code
that?ll highlight the issue at hand
Here?s the 50 foot view: Each R & T is comprised of 30 ?words?, words
are 16 wide. ?Today? current design reflects individual classes for
each message:
struct Aircraft_Id : Subject < Aircraft_Id > {
unsigned int const ac_id ;
void Set_Id ( unsigned int const id ) {
ac_id = id ;
Notify () ;
}
};
class Base {
protected :
Aircraft_Id obj_Ac_Id ;
Bridge obj_Bridge; // bridge is a singleton
public :
virtual ~Base() {}
};
/*
| Now we?re ready
*/
// (R?s) From Aircraft to Observers
class Process_R1 : public Base
{
R1_Msg obj_R1 ;
public :
void Process () {
//Decompose data. Store data with ?Bridge?
obj_Bridge.ac_id = obj_R1.Get_Ac_Id () ;
msg_count ++ ; // part of Base
}
};
// etc. for Rn
// (T?s) From Observers to Aircraft
class Process_T1 : public Base, Observer< Version_Info* > {
T1_Msg msg ;
public :
void Update ( Version_Info* subject ) {
// update T1
msg_count ++ ; // part of Base
}
};
//etc for Tn
At issue: there are cases where there?s a need to ?echo? back a
response from an R in a T. ex:
class Process_R1 : public Base {
static int const Type_Info = 0x17DC;
R1_Msg obj_R1;
T1_Msg obj_T1 ;
public :
void Process () {
if ( msg.Get_Test_Msg () == Type_Info ) {
obj_T1.Set_Test_Msg ( Type_Info ) ; // store it for transmittal
New_T1_Msg = true ; // set flag
}
msg_count ++ ; // part of Base
}
};
Clearly this ?idea? that I could isolate the messages i.e instantiate
the messages within the classes fell apart. Next thought. Create a
class that?ll house all messages.
class Msg_Storage {
// make this class a singleton
public :
R1_Msg obj_R1;
R1_Msg obj_R2;
//etc
T1_Msg obj_T1;
T2_Msg obj_T2;
//etc
};
class Process_R1 : public Base {
public:
Process_R1 ( Msg_Storage& msg )
: Base ( msg )
{}
// The process method now has access to ?T?
};
class Process_T1 : public Base {
public:
Process_T1 ( Msg_Storage& msg )
: Base ( msg )
{}
//
};
Still doesn?t seem elegant, hence I thought why not make the messages
a singleton. This led to my 'trial' project and my initial post.
[...]
As for technical issues in your low level design ... it seems that you
know exactly how lot of different messages you handle before you
compile it. So dynamic vector is overkill. Use array. If you derive
(for example) all handlers from common base class (BaseHandler) then
BaseHandler* makes perfect array element. Also why singletons? You may
simply create one object of each class:
HandlerR1 hR1;
HandlerR2 hR2;
//...
HandlerR666 hR666;
These are valid enough C++ singletons for most cases. Then you can put
your 'singletons' into array:
BaseHandler* handlers[666] =
{
&hR1,
&hR2,
//...
&hR666
}
Good point! I trying put together an example of this.
Mark
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]