在 MVC 模式的 GUI 应用程序中,可以、应该以及如何最好地将控制器与 GUI 布局隔离?

问题描述

我一直在摆弄这个问题一段时间,但似乎无法解决这个困境的特定答案。我一直在构建这个围绕 MVC 样式模式组织的 GUI 程序,但遇到了以下问题:如果熟悉这种架构模式,人们可能知道,“控制器”对象应该处理由来自用户输入的“视图”对象(向用户呈现 GUI 的东西),例如按钮点击。

但是,在某些情况下,对单击按钮的响应可能需要在其中放置另一个视图,例如窗口中的对话框或窗格,具体取决于我们的 GUI 的布局方式。但是在执行此操作时,对我而言,控制器不必担心 GUI 的布局似乎是“合乎逻辑的”,只需要提供这样的视图即可。也就是说,视图具有上下文并嵌套在一起,我们希望控制器不必知道该上下文和嵌套。

然后,诀窍是如何最好地实现这种隔离——或者知道如果没有它真的是“糟糕的设计”,因为最简单和最明显的解决方案是忘记它,让控制器中的视图,控制器必须知道上下文,如果我们重新排列 GUI,则必须更改。但这似乎违背了面向对象编程(本程序使用的)的“单一责任原则”等原则。它给了控制器更多的“改变理由”。这显然不是理想的可以避免的。

我想出的另一种方法是使用一个“视图管理器”,它可以完全控制视图的创建,它知道所有的上下文。但即使在这里,似乎也存在更微妙的知识泄漏,因为在有多个包含视图可用的情况下,“哪个视图与哪个包含视图相配”可能变得模棱两可。如果控制器请求子视图,而不是父视图(不知道,还记得吗?)那么视图管理器在放置子视图的位置上会陷入困境,除非它以某种方式被告知,否则(如在当前程序中),视图管理器只允许一个视图,然后将相同的视图返回给控制器,如果控制器是在假设下设计的,那么控制器就有可能在控制器之间产生微妙的串扰将获得一个单独的视图,仅供自己使用。

对此有更优雅的答案吗?

解决方法

简短的回答:简单地说,你没有。 稍微长一点的答案:MVC 是一种表示模式。这意味着它有助于处理应用的表示层。

不要被“控制器”这个词弄糊涂了:它们不是用来处理业务逻辑的,而是用来将 UI 调用转发到适当的服务。 控制器必须“精简”,只是简单的代理(或者,在极端情况下,从 DTO/ViewModel 到适当的业务模型的映射器)。

确保所有基础工作都被封装并抽象到一个与 UI 无关的层中。