Is this scenario a good use for polymorphic functions

A

Angus

I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.

The base class works out what the type of message is and then calls
the correct inherited class function. Eg if the function were a blah
message which simply responds with the message "Blah" then the base
class would call the Blah class PerformAction function which would
maybe create a blah message response.

Does this seem like a reasonable design in this scenario?
 
V

Victor Bazarov

Angus said:
I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.

The base class works out what the type of message is and then calls
the correct inherited class function. Eg if the function were a blah
message which simply responds with the message "Blah" then the base
class would call the Blah class PerformAction function which would
maybe create a blah message response.

Does this seem like a reasonable design in this scenario?

No.

If the base class is aware of all message types and can know what
function to call for each of them, you don't need the derived types
at all. Just let the single message class do its job.

Here is the scenario where you'd need derived classes and polymorphic
behaviour:

Your "processor" class knows nothing about the types, but it can
register itself in the message dispatcher registry. When registering
the "processor" says what type of message it processes. The
dispatcher then creates a map of instances for each type:

map<message_type, processor_base*> registry;

and any time a message comes the dispatcher gets the type and calls
the processor using the pointer it obtains by looking up the message
type in the registry.

The difference here is (a) the processors are not known ahead of
time, they come from some plug-ins that may or may not exist, and
(b) the number of message types is not necessarily static, it can
change from run to run, when new processors are developed to serve
new message types.

V
 
A

Alexander Dong Back Kim

I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.

The base class works out what the type of message is and then calls
the correct inherited class function. Eg if the function were a blah
message which simply responds with the message "Blah" then the base
class would call the Blah class PerformAction function which would
maybe create a blah message response.

Does this seem like a reasonable design in this scenario?

Hi, Angus

I think you've made a reasonable approach. What I'm understanding
about your development is the system deals with a number of different
types of messages. That way would allow you to extend the system when
more different types of messages should be supported by the system.
Since I haven't fully understand what you are really doing, I believe
the tasks and actions between different types would be significant. If
this is right then, of course, you should make an abstract class for
all the message classes.

Cheers,
 
A

AnonMail2005

No.

If the base class is aware of all message types and can know what
function to call for each of them, you don't need the derived types
at all. Just let the single message class do its job.

Here is the scenario where you'd need derived classes and polymorphic
behaviour:

Your "processor" class knows nothing about the types, but it can
register itself in the message dispatcher registry. When registering
the "processor" says what type of message it processes. The
dispatcher then creates a map of instances for each type:

map<message_type, processor_base*> registry;

and any time a message comes the dispatcher gets the type and calls
the processor using the pointer it obtains by looking up the message
type in the registry.

The difference here is (a) the processors are not known ahead of
time, they come from some plug-ins that may or may not exist, and
(b) the number of message types is not necessarily static, it can
change from run to run, when new processors are developed to serve
new message types.

V
This is very similar to how we do message processing in our servers.
The "pattern" is essentially a factory. I came across the idea of
registering the processors from the Modern C++ Design book.
 
A

Alexander Dong Back Kim

No.

If the base class is aware of all message types and can know what
function to call for each of them, you don't need the derived types
at all. Just let the single message class do its job.

Here is the scenario where you'd need derived classes and polymorphic
behaviour:

Your "processor" class knows nothing about the types, but it can
register itself in the message dispatcher registry. When registering
the "processor" says what type of message it processes. The
dispatcher then creates a map of instances for each type:

map<message_type, processor_base*> registry;

and any time a message comes the dispatcher gets the type and calls
the processor using the pointer it obtains by looking up the message
type in the registry.

The difference here is (a) the processors are not known ahead of
time, they come from some plug-ins that may or may not exist, and
(b) the number of message types is not necessarily static, it can
change from run to run, when new processors are developed to serve
new message types.

V

Hi Victor,

Wow, I envy your deep level of understanding of C++ programming
language and compare to your knowledge, I'm just a novice. I have a
question about your approach though. What if the messages have
different member variables, making and using an abstract class would
be a better idea? For instance, there are two different types of
message class ImageLoadingMessage and TextLoadingMessage. Let say
ImageLoadingMessage contains sender's information as well as pixel
range information like X and Y whereas TextLoadingMessage contains,
again sender's information, and the actual text data. In this case,
isn't that making a super class for the two would be an ideal way of
doing so?

Cheers,
 
A

Alexander Dong Back Kim

This is very similar to how we do message processing in our servers.
The "pattern" is essentially a factory. I came across the idea of
registering the processors from the Modern C++ Design book.

Oh... I missed the part saying "message processing in servers"... =)
 
B

Barry

Angus said:
I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.

The base class works out what the type of message is and then calls

then your base class have to know all message types and remember whom to
dispatch the message. What if a new message type is needed (Maybe you
say that's not the case here). Then I guess you have to borrow *switch*

polymorphic has a usage of avoiding switch/if statement, as they are not
maintainable.
 
V

Victor Bazarov

Alexander said:
[..] What if the messages have
different member variables, making and using an abstract class would
be a better idea?

Maybe. There was not enough information to conclude anything.
For instance, there are two different types of
message class ImageLoadingMessage and TextLoadingMessage. Let say
ImageLoadingMessage contains sender's information as well as pixel
range information like X and Y whereas TextLoadingMessage contains,
again sender's information, and the actual text data. In this case,
isn't that making a super class for the two would be an ideal way of
doing so?

Creating a hierarchy of classes makes sense in may instances. What
you're describing seems to fit this particular scheme:

class AbstractMessage {
enum type { Type0, Type1, .... , TypeN };
type m_type;
virtual ResultType process_type0() { return 0; }
virtual ResultType process_type1() { return 0; }
...
virtual ResultType process_typeN() { return 0; }

protected:
AbstractMessage(type t) : m_type(t) {}
virtual ~AbstractMessage() {}

public:
ResultType process() {
switch (m_type) {
case Type0:
return process_type0();
case Type1:
return process_type1();
...
case TypeN:
return process_typeN();
}
};

class MessageType0 : public AbstractMessage {
ResultType process_type0() { /* use m_str */ return 1; }
std::string m_str;
public:
MessageType0(std::string const & str)
: AbstractMessage(Type0), m_str(str) {}
};

class MessageType1 : public AbstractMessage {
ResultType process_type1() { /* use m_a, m_b */ return 1; }
int m_a, m_b;
public:
MessageType1(int a, int b)
: AbstractMessage(Type1), m_a(a), m_b(b) {}
};

I call it *slightly inelegant*.

V
 
B

Barry

Alexander said:
Hi Victor,

Wow, I envy your deep level of understanding of C++ programming
language and compare to your knowledge, I'm just a novice. I have a
question about your approach though. What if the messages have
different member variables, making and using an abstract class would
be a better idea? For instance, there are two different types of

Yes,
when we don't have C++, in a thread entry function

void thrd_func(void*);

it uses void* for abstraction.

why not have an abstract class for messages.
message class ImageLoadingMessage and TextLoadingMessage. Let say
ImageLoadingMessage contains sender's information as well as pixel
range information like X and Y whereas TextLoadingMessage contains,
again sender's information, and the actual text data. In this case,
isn't that making a super class for the two would be an ideal way of
doing so?
You can provide some helper functions in the super class if the derived
class have some common operations. Actually not sure what you mean.

The thrd_func example again,
the derived class should know how to deal with the abstract data
(pointer/reference) just like thrd_func knows how to deal with the pointer.
 
A

Alexander Dong Back Kim

Alexander Dong Back Kim wrote:






Yes,
when we don't have C++, in a thread entry function

void thrd_func(void*);

it uses void* for abstraction.

why not have an abstract class for messages.


You can provide some helper functions in the super class if the derived
class have some common operations. Actually not sure what you mean.

The thrd_func example again,
the derived class should know how to deal with the abstract data
(pointer/reference) just like thrd_func knows how to deal with the pointer.

Thank you very much Barry and Victor =)
 
D

Daniel T.

Angus said:
I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.

The base class works out what the type of message is and then calls
the correct inherited class function. Eg if the function were a blah
message which simply responds with the message "Blah" then the base
class would call the Blah class PerformAction function which would
maybe create a blah message response.

Does this seem like a reasonable design in this scenario?

I will give you a heuristic... If making a base class and two or more
subclasses will allow you to remove one or more switch or if statements,
then go ahead and use polymorphism, otherwise don't.
 
J

James Kanze

I am developing a server which receives a range of different
messages. There are about 12 different message types so I thought
that a good idea would be to devise a class for each message type.
Then in my base class I for example have a pure virtual function
called eg PerformAction. Then in each message class I implement
PerformAction.
The base class works out what the type of message is and then calls
the correct inherited class function. Eg if the function were a blah
message which simply responds with the message "Blah" then the base
class would call the Blah class PerformAction function which would
maybe create a blah message response.
Does this seem like a reasonable design in this scenario?

Not per se. If the base class has to work out the message type,
and call a different function, then there's no point in
derivation.

If it's possible to determine the action from some information
at the beginning of the buffer, then it would be reasonable to
use that information to create a derived class of the correct
type; in this case, the base class doesn't need to work out
anything, it just calls its virtual "doAction" function. You
still need to work out which type of object to create, but this
can typically be done by looking up a factory in a table or map,
and calling the factory function for the actual construction.

In other cases, it might make more sense to have a class with
the message itself, and use the strategy pattern for the action;
the base class then determines the correct strategy to
instantiate (again, by means of table lookup and a factory).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top