Closed. This question is
opinion-based。它当前不接受答案。
想改善这个问题吗?更新问题,以便
editing this post用事实和引用来回答。
1年前关闭。
Improve this question
我正在使用libssh2创建一个用于执行SSH命令的C++类。
libssh2 SSH session 的生命周期经历以下阶段:
初始化(获取本地资源)
握手/身份验证(在远程计算机上建立SSH session
主机)
断开连接(终止远程主机上的SSH session )
Free(释放本地资源;如果需要,还执行步骤3)。
在步骤1之前,我们必须打开一个套接字,然后在步骤2中将其传递给libssh2。从那时起,我们不再需要传递该套接字,因为libssh2将存储对该套接字的引用。步骤4之后,我们可以关闭插座。
我通过一个类(
SSHSession
)公开了这一点,我希望在ctor上进行设置(步骤1和2),而在dtor上进行拆解(步骤3和4)(因为步骤2非常耗时,所以将允许我保持 session 池的打开状态并重用它来执行命令)。
我的第一次尝试将所有代码都集中在
SSHSession
上,并且它的ctor很快变得一团糟,“如果此步骤失败,那么我们必须看到已经完成的操作并撤消它”例程; dtor并不那么复杂,但是我仍然觉得它太“忙”。
然后,我将工作划分为几个类,为每个获取/发布步骤实现RAII,即:
步骤1和4。
步骤2和3。
我创建了一个实现了第2步和第3步的
SessionConnection
类,并拥有了一个实现了第1步和第4步的
SessionHandle
类型的成员。它还将套接字作为数据成员,从而创建了对ctor / dtor的一阶依赖关系-套接字不能在
SessionHandle
成员之前销毁。
在考虑设计时,我认为可以像这样安排步骤2和3:
2.1. Handshake (establishes an SSH session on the remote host)
2.2. Authentication
3. Disconnect (terminates SSH session on the remote host)
这意味着我可以进一步简化我的
SessionConnection
类,实现另一个类以在步骤2.1和3上执行RAII,最后得到如下所示:
类SSHSession
具有SessionConnection
数据成员。
类SessionConnection
实现步骤2.2。
SessionConnection
具有套接字数据成员。
SessionConnection
具有SessionHandle
数据成员,该成员实现步骤1和4。必须在套接字之前销毁它。
SessionConnection
具有RemoteSessionHandle
数据成员,该成员实现步骤2.1和3。必须在SessionHandle
数据成员之后创建并销毁该成员。
通过RAII,这极大地简化了我的导师/导师。从概念上讲,我觉得不错;如果,一方面,我们可以将它们视为SSH session 通过的状态;另一方面,我们还可以将它们视为我们正在管理的资源(本地,远程)。
但是,我现在在
SessionConnection
中有一个严格的构造/销毁顺序,尽管我相信这是一种改进(并且我在研究中没有发现“这是邪恶的”,但仅“应该清楚地记录在案”),对其他意见感兴趣,我会很乐意接受有关此设计可能替代品的信息/指针。
到目前为止,我所看的是:
ScopeGuard,ScopeExit。这是类似的机制,我没有找到
我可以用来改进设计的任何东西。
状态机。我找不到一种方法来简化设计,
它并没有解决RAII所解决的一个问题,即如果出现故障则进行清理。
谢谢你的时间。
我是一名优秀的程序员,十分优秀!