这不是一个技术问题,而是一个c ++设计问题。
通常我似乎必须设计必须管理一些具有某种连接的协议的程序,解析阶段和抽象视图。通常情况下,我会尝试将我的程序设计为最前沿的关注点。
我一直以对象的“堆栈”结束,系统位于解析器的顶部,而解析器又位于连接的顶部(通常有更多的层)。然后,这些对象使用成员函数调用来调用它下面的层(Tx),并使用回调(通常为std::function
)来捕获来自其他方向(Rx)的信息。
这种设计似乎非常低,因为它增加了复杂性,每层都必须有一个逐渐变大的构造函数等等。另外因为连接通常使用类似ASIO的东西,回调通常在不同的线程上,因此很难推断线程安全。
是否有更好的设计模式或成语代表这种结构/功能?
一个简单的例子
class basic_connection {
basic_connection(std::string address);
void send(std::string);
std::function<void(std::string)> on_receive;
};
我有几个这样的类,它们保存着该层的状态,并且通过它们的公共成员函数和回调粘合在一起。
上面的层接收网络的命令数据进程并调用basic_connection::send
。并从basic_connection
获取原始数据并转换为未处理的上层图层的命令。
我忘了提到的另一个问题是你最终通过堆栈转发了一些接口,例如,顶层仍然需要知道连接状态。
答案 0 :(得分:1)
没有一套要求,很难推荐任何东西。但是,从您问题中的高级描述中,您似乎可能希望使用模型 - 视图 - 控制器模式,可能与其他模式结合使用。请记住,设计模式是您的朋友,您决定使用的适当性和程度。设计模式很容易被滥用,并且一直在发生。
答案 1 :(得分:1)
听起来你正在尝试做的事情通常被称为“构建管道”。
以下是连接两个图层的一种简单方法:
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);
}
答案 2 :(得分:0)
在我看来,你需要的是额外的抽象。我首先要设计一个通用类型来描述一个层实际是什么,并且(如果合适的话)为每个特定层细化,而不考虑这些层的具体协议。 所以,你可以说一个layer-k协议需要一个layer-(k-1)类型的对象。
从你的描述中我假设你的更高层正在构建它们的直接下层,这使得构造函数膨胀。只需要为构造函数中的下一个较低层请求引用(可能最好由shared_ptr
或unique_ptr
实现),并让接口用户对其实例化感到烦恼。
由于您定义了一个抽象接口,您仍然可以多态地使用较低层,而不必费心如何实现它以及使用什么特定的低层协议。
对于接收,您通常需要可以以相同方式实现的回调。您甚至可以在更高层对象的构造函数中安装,并在析构函数中删除它们。
如果您在设计时知道哪个协议将与哪个协议一起使用,您还可以通过使协议实现成为接收其较低协议的模板来替换多态调用:{{ 1}}。