gpt4 book ai didi

java - MVC在哪里保留对 Controller 的引用?

转载 作者:行者123 更新时间:2023-11-30 08:04:42 25 4
gpt4 key购买 nike

在我的程序中,控制器只是将按键与函数挂钩。
那么ikeep应该引用它吗?
例如。
保持参考

Model model = new Model();
View view = new View(model);
Controller controller = new Controller(model,view);


或者没有

Model model = new Model();
View view = new View(model);
new Controller(model,view);


内部控制器

public Controller(Model model, View view)
{
this.model = model;
this.view = view;
view.setOnKeyPressed(this::doSomething);
}

public void doSomething(KeyEvent event)
{
System.out.println("key pressed");
}


也许我实现了Controller类错误并误解了mvc模式。但是到目前为止,我没有理由继续引用控制器对象。

最佳答案

我不确定这个问题是否真的可以回答,因为它可能范围太广和/或基于观点。然而...

MVC是一个非常松散定义的模式。实际上,它可以追溯到Xerox PARC对GUI开发进行研究的早期约40年(或更长时间)。由于已经存在了很长时间,并且它的主要用例(GUI体系结构)已经发生了很大的变化,因此它已经分支为许多子模式和变体。因此,您会发现“ MVC”对于不同的开发人员而言意味着许多不同的东西。特别是,在您所讨论的上下文中,Web应用程序环境中的MVC(imo)与MVC有所不同,因为在Web应用程序环境中,它必须位于请求-响应周期的顶部。本回答/讨论的其余部分集中于MVC的原始“胖客户端”版本,其中视图和控制器都在同一进程内的内存中,并且可以直接通信(而不是通过诸如HTTP之类的请求-响应协议)进行通信。 )。

对我而言,在桌面GUI上下文中MVC的权威指南是Martin Fowler的essay on GUI architectures

我会说“经典” MVC的特点是:


具有三个组成部分:


提供对数据的访问的模型可以提供用于注册侦听器以通知数据更改的机制,并且不了解数据的表示形式
一个视图,该视图观察模型中的数据并在数据更改时进行更新(这将经典MVC与某些形式的MVP区别开)
一个提供“视图逻辑”的控制器:通常,这意味着它响应用户输入并更新模型(不是视图)



因此,模型应该完全不了解视图和控制器。该视图对控制器一无所知,但是需要引用模型,以便它可以显示数据并观察数据的变化,从而相应地更新显示。控制器还需要参考模型,因此它可以根据用户输入更新数据。通常,控制器还需要引用视图,因为它通常需要在视图中的小部件上注册事件处理程序,以便了解其必须处理的用户输入。

该设计背后的推动力是允许保持同步的数据的多个呈现(将呈现视为视图和控制器的组合)。该模式通过引用模型中的所有内容来实现此目的:一个演示文稿的控制器可能会更新模型;由于所有视图都遵循模型,因此它们都看到了这些更改,并且每个视图都负责相应地更新自身。更改视图的控制器无需知道其他正在观察数据的视图即可使所有视图保持同步。

您的应用程序本身肯定需要访问模型。它可能需要访问数据,可能需要从外部(即非用户驱动的)因素对其进行修改,并在关闭时持久保存数据,等等。您的应用程序可能需要访问该视图(它需要将其显示在某个地方,可能需要处置它在关机时等)。您的应用程序可能需要访问控制器,也可能不需要。以最纯粹的形式,一旦控制器知道如何观察用户事件的视图,并且知道如何更新模型,您就不再需要与之通信。 (如果要更改“外部”事件的状态,请通过模型而不是通过控制器进行。)

这个想法出现了几种变体(请参阅Fowler)。一种流行的模型(也有其自身的几种变体)是Model-View-Presenter。在该变体中,控制器由“演示者”代替,该“演示者”承担更新视图的部分甚至全部职责。在这种形式的一种形式(Fowler称之为“被动视图”)中,该视图完全没有逻辑,仅布置了控件。演示者处理用户输入,并在视图上发生用户输入时更新视图和模型,并观察模型并在视图发生更改时对其进行更新。此变量在可测试性和调试能力方面具有优势,但是可以说,视图和演示者之间的耦合比视图和控制器之间的耦合更紧密。 (为一个视图提供多个控制器相对容易;为一个被动视图提供多个演示者变得更加复杂,并且演示者通常必须彼此了解一些知识。)

JavaFX实际上为这种架构风格提供了“开箱即用”的支持,它使用FXML作为(通常是被动的)视图,并提供了方便的方法来挂接到它所谓的控制器(也许更多是演示者) 。 JavaFX属性使编写模型变得容易,可以根据需要由视图或演示者观察到。

在实践中,通常会在大多数情况下找到这些工作的最佳组合。一个中大型应用程序将在多个地方,以多个不同的比例使用MVC / MVP类型的模式。您通常会发现,控制器/演示者之间相互了解并在它们之间进行通信很方便,在这种情况下,您显然需要保留对控制器的引用。

因此,您的问题的答案可能只是“取决于您的需求”。如果您不需要对控制器的引用,则无需保留一个。实际上,在JavaFX中FXML的标准用法中,仅在视图(FXML)中指定了控制器类。 FXMLLoader从该信息实例化控制器,并根据需要将视图和控制器连接在一起。您通常甚至根本根本没有在代码中引用控制器实例。但是,如this popular JavaFX question所示,如果需要,您肯定可以得到一个。在完全“纯”的经典MVC中,所有状态更改都是通过模型进行的,并且视图可以观察到它,因此您无需访问控制器。 Fowler指出了一些不错的示例,这些示例听起来并不干净:首先,某些状态和关联的逻辑实际上是视图的一部分,并且在模型中没有位置;其次,注册/通知机制可以很难调试您的应用程序。

关于java - MVC在哪里保留对 Controller 的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35438550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com