C++ 需要很多类的前向去极化是否意味着糟糕的设计

C++ 需要很多类的前向去极化是否意味着糟糕的设计,c++,forward-declaration,C++,Forward Declaration,在我的项目中我有三门课。让我们将它们称为MainWindow、ProcessUserInput、InitialUIPreparer MainWindow的工作就是通过按钮、文本、组合框等与用户对话 ProcessUserInput将使用从MainWindow获取的值进行一些计算,计算完成后,它会将一些处理后的数据发送回MainWindow 并且InitialUIPreparer会计算一些应该在主窗口上绘制的形状的位置,它只会传递坐标而不会绘制它们。但它还需要获得一些数据,如窗口大小等 好的,问题

在我的项目中我有三门课。让我们将它们称为MainWindow、ProcessUserInput、InitialUIPreparer

MainWindow的工作就是通过按钮、文本、组合框等与用户对话

ProcessUserInput将使用从MainWindow获取的值进行一些计算,计算完成后,它会将一些处理后的数据发送回MainWindow

并且InitialUIPreparer会计算一些应该在主窗口上绘制的形状的位置,它只会传递坐标而不会绘制它们。但它还需要获得一些数据,如窗口大小等

好的,问题开始于MainWindow需要从每个类获取数据,类需要从MainWindow获取数据。这导致了循环依赖。我通过将MainWindow.h包含到“ProcessUserInput”和“InitialUIPreparer”中来解决这个问题。但只需在主窗口中使用前向Declaration,如“类ProcessUserInput”和“类InitialUIPreparer”


当然,我仍然可以继续发展。但就像在我的案例中,需要多次向前去宽容,表明设计是否糟糕,我是否应该重新考虑未来项目的设计

仅仅存在转发声明本身并不是一种代码味道。然而,需要转发声明的原因可能是

在您的例子中,您需要转发声明来构造循环依赖性那是你的代码气味。循环依赖性的存在总是一种代码味道——这并不是说它总是一种设计缺陷,而是应该加以注意的东西


特别是在小程序中,循环依赖实际上可能是一个理论设计缺陷,但可能不值得修复。在您的例子中,有两个类直接相互通信。在一个大型的生产系统中,我通常会将这种设计归类为“已损坏;需要修复”。我修复它的方法是引入某种消息总线,或者引入一种独立于这两个类的接收/提供机制,并让每个类与其通信,而不是彼此通信。构建这个系统要么需要花费大量的工作,要么需要花费大量的资金(购买一个),并为一系列新的bug和挑战开辟了道路。对于小型系统,我可能甚至不会费心。

一般来说,向前声明类本身并不表示设计不好:当运行时依赖层次结构是双向的时,这种情况经常发生。但是,当依赖关系图非常密集(即几乎每个类都依赖于几乎所有其他类)时,就有理由开始担心:

在您的情况下,以与模型-视图-控制器设计模式一致的方式分离类可能会使您受益。具体来说,您可能需要引入另一个类,我们称之为
Model
,它将保留需要在其他类之间共享的所有信息。每个类都会从共享的
模型中提取它需要的信息,并将它生成的信息也放入模型中。通过这种方式,单个类将能够用对
模型的单个依赖项替换对所有类的依赖项
类:


ProcessUserInput
听起来像是一个函数(它是一个动词短语)。(相关)很抱歉,这只是一个例子,如果你有任何建议,我会纠正它。真正的问题发生在我的个人项目上现在我在工作,我突然想问这个问题。我记不起真正的类的名称:)。
InitialUIPreparer
从设计的角度看,对我来说是可疑的。为什么不把它合并到主窗口中呢?@vines在我的项目中,我正在模拟一种叫做“麦克风阵列”的东西。有很多形状我应该根据一些形态参数来计算。这将是如此沉重的主窗口,它应该只是画。谢谢你的建议,我也想问一下我的代码是否有味道。我应该将标题改为“需要许多类的前向去极化是否表明设计不好”感谢您的解释,我将更仔细地检查模型-视图-控制器设计。@KadirerDemir还将研究一下,您的
UIPreparer
类可能已经是一个ViewModel了。