I've been reading about MVC a lot recently, because I need to learn how to separate model and GUI for a project in school. (The teacher has said nothing about it, so I'm trying to learn it myself.)
I believe I understand the bacis principles with the view "registering" with the model with actionlisteners, or something along those lines. But I just can't get it into code. I've looked at several small programs, but they are somehow still too big for me to understand the basics.
Could someone please explain it as if explaining to a 5 year old, or give me some links or a really simple example program or something? Thanks a lot!
First, you need to understand the Observer pattern.
The basic idea is that you define an object that notifies interested parties when it changes. (Note that the Observer pattern is a bit more general - Observables notify Observers about "some event". For MVC, that event is "something changed")
First you define a contract between the OBSERVABLE and 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);
}
Then you define the 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);
}
}
This allows any other object to "listen" for changes on the thing it's interested in, as long as it implements that observer interface.
For example:
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);
}
}
Creates an instance of the observable (the Person), registers an observer (TestObserver), and then interacts with the Observable. When run, we see
Property 'name' changed to 'Scott'
Property 'age' changed to 'Scott'
So far so good.
Now let's call the Person our MODEL. The MODEL represents the data that we want to manipulate and view.
We can do this in a "user interface". The user interface can be, but is not limited to:
The code for each of these types of user interfaces (UIs) can be drastically different, but the concepts are the same.
The user interface (UI) allows a user (a person or another computer for example) to see information about the model and make changes to that information.
The "View" is the part of the UI that displays the information for the user. It reads data from the model and formats it in some way to present it.
If the model changes, the View must be updated. To accomplish this, it registers observers with the model. Those observers simply refresh the relevant parts of the presentation in the View.
Now what happens if the user wants to make a change?
We define a "Controller" in the UI as code that interprets user interaction with that UI. For example, if the user types in the "name" field, the controller may interpret that as "change the value of 'name' to the text the user has typed. The controller makes a
person.setName(textFromField);
call to update the model.
Remember what that setName() method does? It notifies the observers of the change. This will cause the UI to update its view.
Note that "view" and "controller" do not need to be separate classes; they're often combined. It's really the roles of "view" (the part of the UI that displays model data) and "controller" (the part of the UI that interprets user interaction and updates the model) that are important to understand.
In some settings, such as Web Applications, the view and controller are very separate. The controller interprets the HTTP requests that are made to the server and updates the mode. The view renders HTML responses to the user. (If you're doing an AJAX application, the design is a bit more similar to a GUI)
The cool thing about the MVC separation (Model vs UI) is that you can add or remove UIs from the Model at any time, and can have multiple UIs on the same model. If data is changed in one UI, all other UIs are updated to reflect the change.
Cool, eh?
Now, the very basic thing about MVC is to separate M, V and C.
On one side you have your classes, and code that does something, like calculate sum of two input numbers, or does something with database, whatever. That's your Model.
On the other side you have some other classes which are responsible for forms, text inputs, buttons and things visible on the screen. That's the View.
Now, Controller is the one linking these two. Usually (in say Swing) you would have your controller implement the Listener interfaces, then you would add the controller as your listener to the screen components you want your software to react on, like buttons. And the implemented handler method wouldn't do anything else except calling whichever method you have implemented in you Model.
I hope this made it more clear..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With