Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ design, how to represent different stages of a protocol with objects

This is not so much of a technical question, but rather a c++ design question.

Frequently it seems that I have to design programs which have to manage some a protocol which has some sort of connection, parsing stage and abstract view. Typically I try and design my programs with separation of concerns at the forefront.

I keep ending out with "stacks" of objects, a system sits ontop of a parser, which in turns sits ontop of a connection (often there are more layers). These objects then use member function calls to call a layer below it (Tx), and uses callbacks (std::function, usually) to capture information coming from the other directions (Rx).

This design seems really subpar, as it add complexity, and each layer has to have a progressively bigger constructor and so on. Also because the connection usually uses something like ASIO, the callbacks are generally on different threads so it's hard to reason about thread saftey.

Is there a design patterm, or idiom that represent this structure/functionality better?

EDIT

A simple example

class basic_connection {
     basic_connection(std::string address);

     void send(std::string);
     std::function<void(std::string)> on_receive;
};

I have a few classes like this, which hold that layer's state, and are glue together by their public member functions and callbacks.

The layer above this, receives command data processes for the network and calls basic_connection::send. And takes the raw data from basic_connection and converts into commands for the layer above it unprocessed.

EDIT2:

Another issue that I forgot to mention is that you end up forwarding some of the interface though the stack, for example, a top layer still needs to know the connection status.

like image 409
111111 Avatar asked Nov 04 '12 16:11

111111


2 Answers

Without having a set of requirements it's hard to recommend anything. However, from the high level description in your question it seems that you might want to use the model-view-controller pattern, maybe in conjunction with others. Remember, design patterns are your friends and you're the one who decides if usage is appropriate and to what degree. Design pattern are very easy to abuse and it's happening all the time.

like image 100
SomeWittyUsername Avatar answered Sep 24 '22 16:09

SomeWittyUsername


It sounds like what you are trying to do is what is normally refered to as "constructing a pipeline".

Here is one simple way to connect two layers:

class I
{
    virtual void a() = 0;
    virtual void b() = 0;
}

class X
{
    I& m_i;

    X(I& i) : m_i(i) {}

    void onRecv(const char* data, size_t len)
    {
        for (size_t p = 0; p < len; p++)
            switch (data[p])
            {
            case 'a': m_i.a(); break;
            case 'b': m_i.b(); break;
            }
    }
}

class Y : public I
{
    void a() { ... }
    void b() { ... }
}

int main()
{
    X x;
    Y y(x);

    while (...)
        x.onRecv(data,len);
}
like image 20
Andrew Tomazos Avatar answered Sep 21 '22 16:09

Andrew Tomazos