【问题标题】:MVC - How to I understand it? (java)MVC - 我如何理解它? (爪哇)
【发布时间】:2011-05-23 04:18:33
【问题描述】:

我最近一直在阅读有关 MVC 的大量内容,因为我需要学习如何在学校的项目中分离模型和 GUI。 (老师没说什么,所以我自己去学习。)

我相信我理解 bacis 原则,即使用 actionlistener 向模型“注册”,或者类似的东西。但我就是不能把它变成代码。我看过几个小程序,但它们对于我来说仍然太大而无法理解基础知识。

有人可以解释一下,就像向 5 岁的孩子解释一样,或者给我一些链接或一个非常简单的示例程序之类的吗?非常感谢!

【问题讨论】:

  • 请注意,您询问的是GUI MVC,这与Web MVC 不同。我敢打赌,你会得到的大部分答案都与第二个有关。
  • @Javier:不用担心 :) 感谢“actionlisteners”,我明白了他的问题。
  • @Rickard:也请务必阅读 zengr 的回答。一旦你放弃 Swing 并开始编写 web 应用程序,它就会派上用场

标签: java model-view-controller


【解决方案1】:

首先,您需要了解观察者模式。

基本思想是定义一个对象,当它发生变化时通知相关方。 (请注意,观察者模式更通用 - 可观察对象通知观察者有关“某些事件”。对于 MVC,该事件是“发生变化”)

首先你在 OBSERVABLE 和 OBSERVER 之间定义一个契约

package aaa;

// AN OBSERVER INTERFACE
// This is a contract between an interested party (the OBSERVER) and
//   the thing it would like to know has changed (the OBSERVABLE)
// The OBSERVABLE will call this method whenever its data changes
public interface SomethingChangedListener {
    void somethingChanged(String name, Object newValue);
}

然后你定义 OBSERVABLE

package aaa;

import java.util.ArrayList;
import java.util.List;

// An OBSERVABLE class
public class Person {
    // STEP 1: keep track of "who cares"
    //         outsiders with interest implement the observer interface
    //         and register with the person to indicate that they care
    private List<SomethingChangedListener> listeners = new ArrayList<SomethingChangedListener>();
    public void addSomethingChangedListener(SomethingChangedListener scl) {
        listeners.add(scl);
    }
    public void removeSomethingChangedListener(SomethingChangedListener scl) {
        listeners.remove(scl);
    }

    // STEP 2: be able to notify those observers by calling a method in the observer interface
    protected void fireSomethingChanged(String name, Object newValue) {
        for (SomethingChangedListener scl : listeners) {
            scl.somethingChanged(name, newValue);
        }
    }

    // STEP 3: whenever the data changes, notify the observers
    private String name;
    private int age;

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
        fireSomethingChanged("age", name);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
        fireSomethingChanged("name", name);
    }
}

这允许任何其他对象“监听”它感兴趣的事物的变化,只要它实现了那个观察者接口。

例如:

package aaa;

public class Test1 {
    private static class TestObserver implements SomethingChangedListener {
        @Override public void somethingChanged(String name, Object newValue) {
            System.out.println("Property '" + name + "' changed to '" + newValue + "'");
        }
    }
    public static void main(String[] args) {
        Person p = new Person();
        p.addSomethingChangedListener(new TestObserver());
        p.setName("Scott");
        p.setAge(43);
    }
}

创建一个可观察对象(Person)的实例,注册一个观察者(TestObserver),然后与可观察对象交互。运行时,我们看到

Property 'name' changed to 'Scott'
Property 'age' changed to 'Scott'

到目前为止一切顺利。

现在让我们将 Person 称为我们的模型。 MODEL 代表我们想要操作和查看的数据。

我们可以在“用户界面”中执行此操作。用户界面可以是但不限于:

  • 图形用户界面 (GUI)
  • 命令行界面 (CLI)
  • Web 应用程序(HTML、JSP、ASP 等)
  • Web 服务(SOAP、REST 等)

每种类型的用户界面 (UI) 的代码可能截然不同,但概念是相同的。

用户界面 (UI) 允许用户(例如一个人或另一台计算机)查看有关模型的信息并对这些信息进行更改。

“视图”是为用户显示信息的 UI 部分。它从模型中读取数据并以某种方式对其进行格式化以呈现它。

如果模型发生变化,则必须更新视图。为此,它将观察者注册到模型中。这些观察者只需在视图中刷新演示文稿的相关部分。

现在如果用户想要进行更改会发生什么?

我们在 UI 中将“控制器”定义为解释用户与该 UI 交互的代码。例如,如果用户在“name”字段中键入,控制器可能会将其解释为“将 'name' 的值更改为用户键入的文本。控制器生成一个

person.setName(textFromField);

调用更新模型。

还记得 setName() 方法的作用吗?它通知观察者这一变化。这将导致 UI 更新其视图。

注意“view”和“controller”不需要是单独的类;它们经常结合在一起。真正需要理解的是“视图”(显示模型数据的 UI 部分)和“控制器”(解释用户交互和更新模型的 UI 部分)的角色。

在某些设置中,例如 Web 应用程序,视图和控制器是非常分离的。控制器解释向服务器发出的 HTTP 请求并更新模式。视图将 HTML 响应呈现给用户。 (如果你在做一个 AJAX 应用程序,设计有点类似于 GUI)

关于 MVC 分离(模型与 UI)的酷点在于,您可以随时在模型中添加或删除 UI,并且可以在同一个模型上拥有多个 UI。如果一个 UI 中的数据发生更改,则所有其他 UI 都会更新以反映更改。

很酷,嗯?

【讨论】:

  • 哇,谢谢,现在我们开始讨论了!但是控制器会从哪里进来呢?在 UI 类中?还是单独上课?还是由我决定?
  • “视图”和“控制器”可能是也可能不是单独的类。通常将它们放在一起更容易,而将它们分开并不总是允许重用。 (尽管在 Web MVC 设置中,它们是非常独立的)。
  • 如果 Person 类有一个“House”类和一个“Pet”类等等,我必须为每个类创建一个监听器列表,对吗?
  • 这取决于... 您可以在 UI 中为模型中的所有内容设置侦听器,或者您可以让 Person 侦听其组成部分并代表他们发送更改消息。或者,您可以定义一个更高级别的 Model 类来跟踪所有较低级别的模型对象并报告它们的更改。这是“视情况而定”的情况之一,我已经通过几种方式做到了。请注意,通常最好听个别部分,这样您就可以使用特定的子 UI 来处理特定部分(如宠物编辑窗口)
【解决方案2】:

现在,关于 MVC 的非常基本的事情是分离 M、V 和 C。

一方面,你有你的类和代码来做一些事情,比如计算两个输入数字的总和,或者对数据库做一些事情,等等。那是你的模型。

另一方面,您还有一些其他类负责表单、文本输入、按钮和屏幕上可见的东西。这就是视图。

现在,控制器是连接这两者的一个。通常(比如说 Swing)你会让你的控制器实现监听器接口,然后你会将控制器作为你的监听器添加到你希望你的软件做出反应的屏幕组件中,比如按钮。并且实现的 handler 方法除了调用您在模型中实现的任何方法之外不会做任何其他事情。

我希望这能让它更清楚..

【讨论】:

  • 我认为控制器计算了两个输入的总和,模型保存了这两个值。
  • 不.. 这就是重点。控制器除了“转发”之外什么都不做。保存值和计算通常都在模型中完成。 “持有价值”部分通常称为领域模型,而“计算”部分是服务层。
  • 确实说得更清楚了,虽然我还是不明白如何实现从控制器到模型的监听器。
  • 这里有一些例子:life.csu.edu.au/java-tut/uiswing/learn/index.html 只要确保有一个单独的类(控制器)实现侦听器接口,然后不要将this 对象添加为侦听器,而是添加控制器。
  • 请务必亲自尝试教程中的解决方案。即使不符合理论上的 MVC,也值得体验。请记住,最终编程是在手指中..
【解决方案3】:

This 图或许可以帮助你理解Java中MVC的关系

UI 组件是 View,Control servlet(只需在此处捕获所有传入请求并将它们重定向到正确的业务对象)是 Controller,而业务对象是 Model。

这就是我对 Java 中的 MVC 的解释。欢迎其他答案。

【讨论】:

  • 我在那个主题中根本看不到任何图形,太奇怪了!不过我很想看看。
猜你喜欢
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 2021-03-11
  • 2020-08-18
  • 2013-07-25
  • 1970-01-01
  • 2020-07-24
相关资源
最近更新 更多