Module
s in the program communicate with each other by using Message
.
Sometimes, one object receives two different types of messages from two different objects.
The communication happens by having an object put messages into queue at other side of objects (maybe through mediator).
To clarify example:
class Message {};
class MsgTypeA : public Message {};
class MsgTypeB : public Message {};
class MsgTypeC : public Message {};
...
// Other modules derived from Module
override accept_msg(), is_full(), and run()
class ModuleA : public Module {
public:
// Subclasses override accept_msg to accept specific type of messages
virtual bool accept_msg(Message* msg) {
// The problem (usage of dynamic_cast)
if (dynamic_cast<MsgTypeA*>(msg)) { // Module only accepts certain concrete class(es)
// The problem (usage of typeid)
queue[typeid(msg)].push_back(msg);
}
}
virtual bool is_full(std::type_index x) {
// The problem
return queue[x].full(); // assume std::vector supports full()
}
virtual void run() {
if (queue[something].empty()) {
// handler for the message type
}
if (queue[something].empty()) {
// handler for the message type
}
...
private:
// The module can have multiple queues
// because a number of modules can send messages to the specific module
// using different types of messages.
std::map<std::type_index, std::vector<Message*>> queue;
};
class ModuleB : public Module {
public:
virtual bool accept_msg(Message* msg) {
// The problem (usage of dynamic_cast)
if (dynamic_cast<MsgTypeB*>(msg)) {
..
}
}
...
};
This is similar to acyclic visitor pattern? where each visitor (message) needs to be accepted by module.0
I think this is not kind of if...else... stupid and wonder whether this design is reasonable to use typeid and dynamic_cast.
If it is avoidable and undesirable, what is the reasonable ways to achieve this kind of situation?
Aucun commentaire:
Enregistrer un commentaire