Piszę kod obsługi komunikatów, przy czym każda wiadomość jest strukturą POD. Na sposób pisania tego byłoby zdefiniować abstrakcyjną klasę bazową, z wirtualnym functiosn dla każdego typu wiadomości npImplikacje używania mpl :: inherit_linearly do definiowania interfejsów
class AbstractHandler
{
public:
virtual void handleMessage(const MessageType1& msg) =0;
virtual void handleMessage(const MessageType2& msg) =0;
virtual void handleMessage(const MessageType3& msg) =0;
virtual void handleMessage(const MessageType4& msg) =0;
};
a następnie utworzyć pochodzących konkretnych klas, które implementują funkcje Handler:
class ConcreteHandler : public AbstractHandler
{
public:
virtual void handleMessage(const MessageType1& msg);
virtual void handleMessage(const MessageType2& msg);
virtual void handleMessage(const MessageType3& msg);
virtual void handleMessage(const MessageType4& msg);
};
Jeśli nowe wiadomości są dodawane do systemu AbstractHandler
muszą być aktualizowane wraz ze wszystkimi wyprowadzonymi typami.
Ewentualnie mogę przechowywać wszystkie obsługiwane typy wiadomości w sekwencji mpl
i używać mpl::inherit_linearly
do generowania abstrakcyjnej klasy bazowej.
(Uwaga: Ja już używać mpl::vector
typów komunikatów gdzie indziej w kodzie).
np: koparki
typedef mpl::vector< MessageType1, MessageType2,
MessageType3, MessageType4 > message_types;
template< class Message >
class Wrapper
{
public:
virtual void handleMessage(const Message& msg) = 0;
protected:
~Wrapper(){}
};
class AbstractHandler
: public mpl::inherit_linearly< message_types
, mpl::inherit< mpl_1, Wrapper<mpl::_2> >
>::type
{
public:
virtual ~AbstractHandler() {}
};
betonowe następnie czerpać z AbstractHandler
. Oznacza to, że gdy do systemu dodawane są nowe typy wiadomości, jest to po prostu przypadek zmiany sekwencji mpl::vector<types...> message_types
, dodania nowych funkcji handleMessage
do klas pochodnych.
Moim zdaniem ta zmniejsza utrzymanie długoterminowego, ponieważ AbstractHandler automatycznie mieć czyste funkcje wirtualne dla wszystkich wiadomości w mpl::vector message_types
Pod względem wydajności czy są jakieś wady do korzystania z tej metody?
Jakie są konsekwencje użycia mpl::inherit_linearly
do generowania abstrakcyjnych klas bazowych?
dzięki za potwierdzenie moich przemyśleń na ten temat. Mam teraz działające rozwiązanie, które jest częścią interfejsu API używanego przez usługi klienta podczas przetwarzania komunikatów. Do tej pory wszyscy użytkownicy lubią API ... MPL z pewnością pomaga w tworzeniu solidnego kodu ... – mark
Po stronie użytkownika ma jednak kilka wad: mniej oczywiste jest, jakie funkcje należy zdefiniować. Dobry (najnowszy) kompilator da wyraźny komunikat, więc myślę, że jest w porządku. Byłoby również lepiej, gdyby istniał sposób zmuszenia użytkownika do wyraźnego nadpisania funkcji (aby upewnić się, że nie popełniają błędów). – Klaim