3 java model-view-controller swing design-patterns
我不想尝试遵循MVC模式.在互联网上,我看到最着名的例子是计算器,例如这里.我开始使用这种MVC模式的实现.但是现在我对控制器中的动作监听器有些疑虑,因为它们倾向于查看.
有很多变化与视图相关的主要原因 - 字体,颜色,边框等.此外还有仅仅修改视图的actionlisteners!因此,在控制器中实现这样的actionlistener要困难得多(与视图中的简单内部匿名类相比).此外,它需要从控制器访问许多视图元素.
我有一个想法是在控制器和一些视图中保留一些actionlisteners,但它可能导致将来混乱.所以我想听听其他人的想法.
PS这个问题与许多ActionListener的MVC模式不重复
MVC不是一种"严格"的模式.对原始模式有不同的解释,并且经常使用不同的衍生物,如MVP或MVVM(即使人们说他们使用的是MVC).
最重要的方面是将模型和视图分开.但有关它们如何连接的详细信息可能会有所不同,具体取决于应用案例.
MVC模式最常出现的问题是: "什么是控制器?"
答案:
"获得晋升的会计师"
根据我的个人经验,很少有理由有一个明确的 "控制器"课程.强制在一个"控制器"类中累积和汇总监听器有几个严重的缺点.为了在GUI组件和Model之间建立连接,您有两个选择:一个选项是允许访问视图组件以附加侦听器:
gui.getSomeButton().addActionListener(myActionListener);
Run Code Online (Sandbox Code Playgroud)
我认为这是一个禁忌,因为它暴露了实现细节并阻碍了修改.另一种选择更好 - 即提供允许附加侦听器的方法:
gui.addActionListenerToSomeButton(myActionListener);
Run Code Online (Sandbox Code Playgroud)
但我认为这是值得怀疑的,因为它仍然暴露了一个按钮的事实.例如,当您JTextField输入一个数字,然后JSlider将其更改为a 时,问题可能会变得更加明显:它将更改所需的侦听器类型,尽管它应该只是视图的问题.
在Swing应用程序中,我认为Listener可以被视为"小控制器".我认为拥有直接调用模型方法的匿名监听器是完全可行的(除非有这些调用的附加逻辑).
话虽如此:我不会考虑您作为MVC的"好"示例链接的示例.首先,因为所选示例没有显示MVC的关键点:模型不包含状态,并且MVC 中的模型通常是必须被观察的事物(因此,作为Listeners附加)不清楚.其次,由于上面提到的要点,因此建立GUI与模型之间的连接的方式是有问题的.
我喜欢http://csis.pace.edu/~bergin/mvc/mvcgui.html上的例子.它的一部分也可能受到质疑(例如,使用通用的Observer/Observable类),但我认为它以令人信服的方式很好地展示了MVC的基本概念.
编辑:没有以ZIP的形式下载此示例.但是,你可以复制和粘贴TemperatureModel,TemperatureGUI,FarenheitGUI和MVCTempConvert成一个IDE.(它假定CelsiusGUI存在一个.这CelsiusGUI在网站上被省略,但在结构上与Farenheit GUI相同.对于第一个测试,实例化它的行可能只是被注释掉).
添加侦听器的选项在此示例中由抽象TemperatureGUI类提供.在实际的侦听器创建和附加的具体 FarenheitGUI类.但这或多或少是一个实现细节.这里的关键点(也是针对原始问题)是监听器是由View 创建的,以内部类甚至是匿名类的形式.这些侦听器直接调用模型的方法.即,将温度设置为Farenheit(对于Farenheit GUI),或设置以摄氏度为单位的温度(对于Celsius GUI).
仍有一定程度的自由.它不是一个"完美"或"通用"的MVC示例.但是,到目前为止,我发现的恕我直言比其他大多数MVC更好,因为它很好地展示了重要的方面:
Observable Observer在更复杂的常规设置中,不会使用Observable/ Observerclasses.相反,人们可以为模型创建专用的侦听器和可能的事件.在这种情况下,这可能类似于TemperatureChangedListener和TemperatureChangedEvent.该Observable/ Observer班在这里已经用于简洁,因为他们已经是标准的API的一部分.
Agin,请注意可能存在更复杂的应用案例,其中在这个小例子中概述的MVC的想法必须稍微扩展.特别是,当有要执行的任务,去超越的模式只是调用方法.例如,当View包含多个输入字段时,在将数据传递给模型之前必须对其进行预处理或以其他方式验证.这样的任务不应该由匿名听众完成.相反,这些任务可以在一个类中概括,然后可以称为"控制器".但是,将实际侦听器附加到GUI组件仍然只能通过View完成.作为一个过于暗示的例子:这可能会发生
// In the view:
someButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
String s = someTextField.getText();
Date d = someFormattedTextField.getDate();
int i = someSlider.getValue();
// The controller validates the given input, and
// eventually calls some methods on the Model,
// possibly using the given input values
controller.process(s, i, d);
}
});
Run Code Online (Sandbox Code Playgroud)