在 MVC 模式的 GUI 应用程序中,可以、应该以及如何最好地将控制器与 GUI 布局隔离?
Posted
技术标签:
【中文标题】在 MVC 模式的 GUI 应用程序中,可以、应该以及如何最好地将控制器与 GUI 布局隔离?【英文标题】:In an MVC patterned GUI application, can, should, and how can one best isolate the controllers from the GUI layout? 【发布时间】:2021-04-09 07:40:31 【问题描述】:我一直在摆弄这个问题,但似乎无法解决这个困境的特定答案。我一直在构建这个围绕 MVC 样式模式组织的 GUI 程序,我遇到了以下问题:如果有人熟悉这种架构模式,那么“控制器”对象应该处理由来自用户输入的“视图”对象(将 GUI 呈现给用户的东西),例如按钮单击。
但是,在某些情况下,对单击按钮的响应可能需要在其中放置另一个视图,例如对话框或窗口中的窗格,具体取决于我们的 GUI 的布局方式。但是当这样做时,对我来说,控制器不应该担心 GUI 的布局似乎是“合乎逻辑的”,只需要放置这样的视图即可。也就是说,视图具有它们的上下文,并且嵌套在一起,我们希望控制器不必知道上下文和嵌套。
那么,诀窍是如何最好地实现这种隔离 - 或者知道没有它是否真的是“糟糕的设计”,因为最简单和最明显的解决方案就是忘记它,让在控制器中查看,并且控制器必须知道上下文,并且如果我们重新排列 GUI,则必须进行更改。但这似乎违背了诸如面向对象编程的“单一责任原则”(本程序使用)之类的原则。它给了控制器更多的“改变的理由”。这显然不是理想的如果可以避免。
我想出的替代方法是使用“视图管理器”,它可以完全控制视图的创建,它知道所有上下文。但即使在这里,似乎也存在更微妙的知识泄漏,因为在有多个包含视图可用的情况下,“哪个视图与哪个包含视图一起使用”可能会变得模棱两可。如果控制器请求子视图,而不是父视图(不知道,还记得吗?),那么视图管理器将在放置子视图的位置上进退两难,除非它以某种方式通知它,否则(如在当前程序中),视图管理器只允许一个视图,然后将相同的视图返回给控制器,如果控制器是在假设下设计的将获得一个单独的视图供自己使用。
有没有更优雅的答案?
【问题讨论】:
【参考方案1】:简短的回答:简单地说,你不知道。 稍微长一点的答案:MVC 是一种 presentational 模式。这意味着它有助于处理应用程序的表示层。
不要对“控制器”这个词感到困惑:它们不是用来处理业务逻辑的,而是用来将 UI 调用转发到适当的服务。 控制器必须“瘦”,只是简单的代理(或者,在极端情况下,从 DTO/ViewModel 映射到正确的业务模型)。
确保所有基础工作都被封装并抽象到与 UI 无关的层中。
【讨论】:
谢谢。这绝对让它更 KISSey。但是,您所说的“基础工作”是什么意思?我猜你的意思是程序的业务逻辑/领域逻辑部分,对吧? 正确。您的领域模型不了解 UI,也不应该了解。这意味着您可以在单独的项目中创建它们并从您的 UI 层引用它。当然,您必须在那里处理与 ViewModel 的映射。 @DavidGuida 不错的答案。 “领域模型”是指领域模型的多个组件?或者,您确实是指每个项目可能有多个领域模型(每个都有多个组件)? @dakis : 这是一个非常广泛的问题 :D 一般的答案是“域模型”是一个对象建模来表示您的系统试图支持的域部分。可以根据上下文重用相同的名称:例如。用户可以代表身份验证服务的某些东西,而它可以代表运输服务的完全不同的东西。 @DavidGuida 谢谢。对我来说,“域模型”实际上是a model of the domain。它的对象(相互连接)我称之为“域对象”,或“实体”。以上是关于在 MVC 模式的 GUI 应用程序中,可以、应该以及如何最好地将控制器与 GUI 布局隔离?的主要内容,如果未能解决你的问题,请参考以下文章