C++设计中,如何用对象表示协议的不同阶段
C++ design, how to represent different stages of a protocol with objects
这不是一个技术问题,而是一个 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
中获取原始数据,并将其转换为未经处理的上层的命令。
编辑2:
我忘了提到的另一个问题是,您最终通过堆栈转发了一些接口,例如,顶层仍然需要知道连接状态。
如果没有一套要求,很难推荐任何东西。但是,从您问题中的高级描述来看,您可能希望使用模型-视图-控制器模式,可能与其他模式结合使用。请记住,设计模式是你的朋友,你是决定使用是否合适以及在多大程度上合适的人。设计模式很容易被滥用,而且这种情况一直在发生。
听起来您要做的是通常所说的"构建管道"。
以下是连接两层的一种简单方法:
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);
}
在我看来,你需要的是额外的抽象。我将首先设计一个通用类型来描述层的实际含义,并(如果适用)针对每个特定层进行细化,而不考虑这些层的具体协议。 因此,您可以说 layer-k 协议需要一个 layer-(k-1) 类型的对象。
从您的描述中,我假设您的较高层正在构造其直接的较低层,这使得构造函数膨胀。只需请求构造函数中下一个较低层的引用(可能最好由shared_ptr
或unique_ptr
实现),并让接口用户为其实例化而烦恼。
由于您定义了抽象接口,因此您仍然可以多态地使用下层,而不必为它的实现方式和使用特定的下层协议而烦恼。
对于接收,通常需要可以以相同方式实现的回调。您甚至可以将它们安装在更高层对象的构造函数中,并在析构函数中删除它们。
如果您在设计时知道哪个协议将与哪个其他协议一起使用,您还可以通过使协议实现成为接收其较低协议的模板来替换多态调用,如下所示:Tcp<Ip<Ethernet<Device>>>
.
- 表示"accepting anything for this template argument" C++概念的通配符
- 如何将ampl中的集合表示为c++中的向量
- std::is_base_of表示ctor编译错误
- 输入中的字符串数未知(以字母表示)
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- c++模板来表示多项式
- 询问在设计我的手臂模拟器功能表示格式1
- CMakeLists.txt中的命名空间表示法
- 如何使用url确定网站协议
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 如何计算Big-O表示法中的平均渐近运行时间
- 我应该如何表示我拥有的连续元素序列?
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- MSYS2 MinGW程序包中缺少grpc_cpp_plugin协议
- 表示类模板C++空类型
- 具有所表示类的相同构造函数签名的代理类模板
- 嵌套在循环中的两个循环的 big-O 表示法
- C++设计中,如何用对象表示协议的不同阶段