所有按钮都应包含对 MVC 代码 (C++) 中控制器的引用吗?

Should all buttons contain a reference to the controller in MVC code (C++)?

我正在尝试找出最佳(最干净)的方式来为我正在构建的应用程序构建 C++ 中的一些代码。我认为 MVC 是可行的方式,但经过大量研究后,我并不完全清楚我做事的方式是否正确。

这里有一个例子来说明我的问题:

型号

我有一个 class,其中包含名为 Canvas 的绘图数据。用于清除 canvas 当前内容的示例函数是 ClearCanvas().

最终,我希望界面中的按钮能够调用此功能并清除canvas。

控制器

我有一个控制器 class 用于 canvas:CanvasController

控制器创建并保存对 canvas 对象的引用:CurrentCanvas

控制器还创建视图:CanvasView 然后在视图上设置对自身的引用:CurrentCanvasView->SetControllerRef(this);

查看

视图由一系列定义 UI 的嵌套 classes 组成。例如,指向相关按钮的层次结构可能是这样的:

CanvasView
-VerticalBox
--HorizontalBox
---Button

在视图的构造函数中,对控制器的引用从视图传递到所有交互元素,例如。 NewButton->SetControllerRef(this->GetControllerRef());

按下按钮

所以现在按下按钮时,它可以像这样工作:

void ClearCanvasButton::OnButtonPressed()
{
    Controller->CurrentCanvas->ClearCanvas();
}

所以我的一般问题是:(1) 这看起来是正确的做事方式还是结构不当?

还有(2):控制器是否应该封装canvas函数,例如:

void CanvasController::ClearCanvas()
{
    CurrentCanvas->ClearCanvas();
}

这样按钮上的功能可以简单地是:

void ClearCanvasButton::OnButtonPressed()
{
    Controller->ClearCanvas();
}

我只是不确定将对控制器的引用传递给最终想要更改模型的视图的所有元素是否正确,或者是否有更简洁的方法。

如果这个问题已经以一千种不同的方式被问了一千次,我深表歉意,我一直在四处寻找以试图理解这一点。

你不需要 class ClearCanvasButton,如果你的 Button class 包含像

std::function<void()> onButtonPressed;

similar,而不是

virtual void onButtonPressed() {};

然后传递一个引用控制器的 lambda

CanvasView::CanvasView()
{
    // make the widgets
    Button.onButtonPressed = [Controller](){ Controller->ClearCanvas(); };
}