c++ - 解决代码中模块之间的相互依赖

标签 c++ design-patterns c++11 architecture software-design

这是一道设计题。我正在研究一个复杂的客户端-服务器架构,其中几个模块(总是在线程中运行)相互依赖并且经常在彼此之间交换信息。在创建所有模块的代码中有一个入口点。在模块较少的代码早期,通过创建和定义它们的关系我没有遇到任何问题。这是一个例子:

auto module1 = std::make_shared<Module1>();
auto module2 = std::make_shared<Module2>(module1);
auto module3 = std::make_shared<Module3>(module1);
auto module4 = std::make_shared<Module4>(module1, module3);
//and so on and so forth

随着模块数量的增加,使模块成为类的一部分成为必要。这样我们就可以在创建模块 B 之前在模块 A 中引用模块 B。这种方法的问题是仅仅头文件中的声明是不够的。因为当您通过 std::make_shared 创建模块时,通过另一个共享指针引用它的模块会丢失引用。所以,这段代码将不起作用:

m_module1 = std::make_shared<Module1>(m_module2);
m_module2 = std::make_shared<Module2>();

std::shared_ptr 在整个代码中使用,所以我无法将其更改为其他内容。我需要另一种方法来解决这个问题。

关于如何实现这个的任何想法?

最佳答案

我对您的问题的解释是,您的系统发生了变化,您现在在模块所需的创建顺序中有一个循环,并且您需要一种技术来打破循环。你的“这不起作用”的例子有点不清楚,但本质似乎是在它存在之前复制一些东西不会打破循环。

最好的方法是检查代码的结构以消除循环而不是破坏它。存在有效创建顺序的第一种方法值得保留,因为代码各部分之间的依赖关系很清楚。

但是,如果您确实有两个强耦合的组件,则基本技术是:

  • 合并导致循环的模块,从而消除循环。
  • 分两步创建一个模块以打破循环。

两步创建是这样的:

auto m1 = std::make_shared<Module1>();
auto m2 = std::make_shared<Module2>(m1);
m1->set_module2(m2);

还有其他方法可以做到这一点,包括传递一个函数对象、传递一个对 shared_ptr 的引用以及传递一个带有方法的上下文对象以检索适当的 shared_ptr<> 值。

如果关于这些对象的创建和相互引用的方式有严格的规则,那么编写一个自由函数或静态成员函数来正确执行并返回对象也是有用的。此函数可以具有模块的实现知识,但函数的用户可以直接调用它。

关于c++ - 解决代码中模块之间的相互依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24986649/

相关文章:

c++ - 具有模板化父类的派生类

c++ - 堆栈或堆上的对象分配

c# - 派生静态成员

c++ - "Inline"带有初始化列表的对象的静态声明

c# - 一个对象应该将自己写到一个文件中,还是应该由另一个对象作用于它来执行 I/O?

design-patterns - 过度关注测试总体上是一件坏事吗?

c++ - 使用 C++11 将我的比较函数传递给 std::multiset

c++ - 智能指针可能的内存泄漏

c++ - 链接列表的总线错误(核心转储)?

c++ - 我在 mac os(英特尔芯片)上构建 opencv 项目时遇到此错误