【问题标题】:Proper model-view-controller design正确的模型-视图-控制器设计
【发布时间】:2011-01-24 06:54:16
【问题描述】:
我有一个 Java 项目,我正在尝试使用模型-视图-控制器设计来实现。我已经建立了所有组件的主干。我在决定如何将它们连接在一起时遇到了一些麻烦,尤其是视图和控制器。
我有一个名为 MainView 的类,它扩展了 JFrame。我还有各种其他类可以帮助组成 MainView,每个类都扩展了 JPanel。例如,这些类之一称为 ParameterView。我应该让控制器看到这些“子视图”中的每一个,还是应该让控制器只看到 MainView 并通过那里管理所有内容?
与模型一样,是否应该通过一个总体类来管理模型?
谢谢!
【问题讨论】:
标签:
java
model-view-controller
user-interface
swing
【解决方案1】:
在 GUI(Swing 类)应用程序的上下文中,模型-视图-控制器更像是一个模糊的建议,而不是一个具体的设计。这种“模式”的变体数量惊人,没有一个“合适的”变体是你应该瞄准的。您可以选择似乎支持您当前需求的任一变体(并随着您的应用程序的发展随时更改它)。
也就是说,这里有一些关于您所描述情况的提示
- 您可以使用发布/订阅机制(AKA:观察者模式)或责任链模式将模型(或其部分)与视图的不同部分分离。
- 封装视图所有部分的外观类(MainView)似乎是“神类”的秘诀:应用程序中几乎任何更改都需要更改的类(反模式)。通过公开视图的不同部分,您将能够更轻松地在新的上下文中重用它们。
- 最后,通过子类化 Swing 组件来实现模型似乎不是一个好主意。这样的设计很难测试,这意味着它也非常严格。更喜欢委托而不是继承。或者正如 JBrains 所说:“停止子类化,否则小猫会得到它”。仅将继承用于覆盖 Swing 方法。立即将所有逻辑委托给与 Swing 完全隔离的对象。这将促进可测试性和未来的灵活性。
【解决方案3】:
层之间的耦合最小是个好主意,所以我可能会允许控制器只看到 MainView。您还应该考虑定义 MainView 实现的接口以使 MVC 结构更清晰。控制器不应该真的需要知道它正在处理一个 JFrame。
【解决方案4】:
暂时忽略 MVC,只将 Swing 特定代码放入您构建的扩展 JComponent 的任何视图组件中。将其他所有内容委托给一个无需 Swing 即可编译的类。使用界面来帮助你。您的控制器应该能够在不知道它们来自 Swing 事件的情况下处理请求。您的模型应该能够在不引用 Swing *Model 类的情况下更新系统的状态。您的 View 应该能够描述如何在不引用 JComponent 类的情况下向用户呈现结果。一旦你完成了这项工作,你就可以轻松地构建委托给你的模型、视图和控制器的 JComponent 对象。
希望对你有帮助。
【解决方案5】:
MVC一般是Observer(模型是可观察的)、Strategy(不同的策略被交换到控制器中来处理不同的视图)和Composite(视图是GUI组件的组合)。
为此,控制器应该观察模型并部署正确的策略来更新您的视图组合。您的 MainView 应该能够呈现从组件传递给它的复合项目(JPanels?)。相反,控制器还应该观察来自 UI 的事件并做出反应,将它们传递给适当的策略。
看看tikeSwing。这是一个用于 Swing 应用程序的简单 MVC 框架,如 here 所述。