最近我一直在阅读有关MVC的内容,因为我需要学习如何将模型和GUI分离,以便完成学校项目。(老师没有讲解,所以我正在自学。)
我相信我已经理解了基本原理,即视图通过操作监听器“注册”到模型上,或者类似这样的操作。但是我就是无法将其转化为代码。我看了几个小程序,但它们对于我来说仍然过于复杂,难以理解基础知识。
能否有人像向5岁孩子解释一样地给我解释一下,或者给我一些链接或一个非常简单的示例程序之类的东西?非常感谢!
最近我一直在阅读有关MVC的内容,因为我需要学习如何将模型和GUI分离,以便完成学校项目。(老师没有讲解,所以我正在自学。)
我相信我已经理解了基本原理,即视图通过操作监听器“注册”到模型上,或者类似这样的操作。但是我就是无法将其转化为代码。我看了几个小程序,但它们对于我来说仍然过于复杂,难以理解基础知识。
能否有人像向5岁孩子解释一样地给我解释一下,或者给我一些链接或一个非常简单的示例程序之类的东西?非常感谢!
首先,您需要了解观察者模式。
基本思想是定义一个对象,在其发生变化时通知相关方。(请注意,观察者模式更为通用 - Observable会通知Observer关于“某个事件”的信息。对于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”。MODEL代表我们想要操作和查看的数据。
我们可以在“用户界面”中完成这个过程。用户界面可以是以下任何一种或多种形式:
每种类型的用户界面(UI)的代码可能会有很大的不同,但概念是相同的。
用户界面(UI)允许用户(例如人或另一台计算机)查看模型的信息并对该信息进行更改。
“View”是UI的一部分,它显示用户的信息。它从模型中读取数据并以某种方式格式化以呈现。
如果模型发生变化,则必须更新View。为了实现这一点,它向模型注册观察者。这些观察者只需刷新View中相关部分的演示即可。
那么如果用户想要进行更改怎么办?
我们在UI中定义一个“Controller”,它是解释用户与UI交互的代码。例如,如果用户在“名称”字段中输入,控制器可以将其解释为“将'名称'的值更改为用户键入的文本。控制器进行了
person.setName(textFromField);
调用更新模型的方法。
还记得setName()方法的作用吗?它会通知观察者发生了变化。这将导致UI更新其视图。
请注意,“视图”和“控制器”不需要是单独的类;它们经常被合并在一起。真正重要的是理解“视图”(显示模型数据的UI部分)和“控制器”(解释用户交互并更新模型的UI部分)的角色。
在某些情况下,例如Web应用程序,视图和控制器是非常独立的。控制器解释发送到服务器的HTTP请求并更新模式。视图呈现HTML响应给用户。(如果您正在进行AJAX应用程序,则设计与GUI有点相似)
MVC分离(模型vs UI)的酷炫之处在于,您可以随时向模型添加或删除UI,并且可以在同一模型上拥有多个UI。如果在一个UI中更改了数据,则所有其他UI都会更新以反映更改。
很酷,对吧?