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:
A Graphical User Interface (GUI)
A Command-Line Interface (CLI)
A Web Application (HTML, JSP, ASP, etc)
A Web Service (SOAP, REST, etc)
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..
This diagram might help you to understand the relationship of MVC in Java
UI component is the View, Control servlet (just catch all the incoming requests here and redirect them to the correct business object) is the Controller and the business objects is the Model.
That is my interpretation of MVC in java. Other answers are welcome.
Related
I'm implementing a project using CQRS and Event Sourcing. I realized that my commands and my events are nearly always the same.
Let's say I have a command CreatePost :
public class CreatePost implements Command {
private final String title;
private final String content;
}
The event fired from this command is the same :
public class PostCreated implements Event {
private final String title;
private final String content;
}
How do you handle that in your applications ?
EDIT : Of course I'm aware of basic OOP technics. I could create an abstraction having the common fields, but this question needs to be taken in the CQRS/ES context.
How to avoid repeating fields between command and event?
I wouldn't -- not until I absolutely can't stand it.
Fundamentally, commands and events aren't objects, they are messages - representations of state that cross boundaries. I think it's important that your in memory representation not lose sight of that.
One of the characteristics of message schemas is that they evolve over time, so you need to be aware of compatibility. And here's the kicker: events and commands evolve on different time scales.
Command messages are how your domain model communicates with other processes; changes to that part of the API are driven by exposing/deprecating functionality.
But in an event sourced world, events are messages from previous versions of the domain to the current version. They are part of the support we need to deploy new models that resume work from where the old model left off.
So I would keep commands and events separate from one another - they are different things.
If you are seeing a lot of duplication in the fields, that may be a hint that there's some value type that you haven't yet made explicit.
CreatePost
{ Post
{ Title
, Contents
}
}
PostCreated
{ Post
{ Title
, Contents
}
}
Simply implement a model for your Post, i.e.:
public class PostModel {
private String title;
private String content;
// Add get/set methods
}
Then re-use this in both your events and commands.
Just compiling this answer from the discussion we had in comments.
Compose, don't inherit
I would definitely not use inheritance in a situation like this because it will just add unnecessary complexity, also there is no behavior to inherit there.
Another option is to have a well-defined contract for your commands and events. That is to have two interfaces — IPost and IEvent — and implement those in the commands and events.
Regarding naming: we all know that naming is hard, so you should choose names wisely, according to your business or technical language/vocabulary requirements.
Why split into two interfaces?
Because a command usually carries more information required for its handler than an event carries for its event handler, event handlers should be kept as thin as possible. It's better to carry only the needed payload.
Closing words
Separating commands and events is a must, since commands are representing an operation that's happening now, whereas events are representing actions that happened in the past. They might usually be an outcome of a command, indicating to the outside world — from the viewpoint of a bounded context — that something happened inside your current BC.
How to avoid repeating fields between command and event?
Just don't. The cost of dependency + risk of wrongful mutualization are higher than the maintenance gain. You can live with that duplication, just like you probably live with duplication between your domain model, view model, query model, etc. today.
You can use whatever you want as long as it is just an implementation detail.
In PHP I use a lot traits for this kind of reusability. You can use even inheritance but the clients (the code that uses those classes) should not depend on the base class; it would be best if they even don't find out that your event and command class share something but I don't have enough Java experience to tell you how to do it.
P.S. I would not go with creating interfaces, as I specified above, this should be just an implementation detail.
I've run into this, and almost universally I've not found a case where the event needed different properties than the command for a particular domain action. I definitely find the menial copy/paste duplication of property getters/equals/hashCode/toString pretty annoying. If I could go back, I'd define a marker interface Action and then
interface Command<T extends Action> {
T getAction();
// other properties common to commands of all action types...
}
class AbstractCommand<T extends Action> implements Command<T> {
public T getAction() { ... }
// other properties...
}
interface Event<T extends Action> {
T getAction();
// other properties common to events of all action types...
}
class AbstractEvent<T extends Action> implements Event<T> {
public T getAction() { ... }
// other properties...
}
Then for each domain action, define concrete implementations.
class ConcreteAction implements Action {
// properties COMMON to the command and event(s)...
}
class ConcreteCommand extends AbstractCommand<ConcreteAction> { ... }
class ConcreteEvent extends AbstractEvent<ConcreteAction> { ... }
If the command and event action properties need to diverge for some reason, I'd put just those particular properties in the ConcreteCommand or ConcreteEvent classes.
The inheritance model here is very simple. You may only rarely need to do anything more than extend the abstract classes with nothing more to implement than the common Action. And in the case where there are no properties needed for the Action, just define a class EmptyAction implements Action implementation to use in those types of commands and events.
We are developing a board game in Java for a school project and we're having an argument with our tutors on the correct implementation of the MVC pattern (that we are required to use).
In our current implementation the View is subscribed as an Observer to some classes in the model, for example the spaces where the pawns can be placed. This spaces have mutable fields, as you can see in the short example below:
public class Space extends Observable {
private List<Pawn> pawns;
private Card card;
// public getters and setters for pawns and card
}
It seemed very intuitive for us to give the View direct reference to this class, in this way we can query the Space every frame to retrieve its status (we are using libgdx for the GUI, so we are updating the window every frame).
Now, even though we are not modifying the Model in the View but just calling the getters, our tutor said this approach wasn't acceptable because we could modify the Model from the View since we are giving direct reference to mutable objects, and wants us to add a layer of indirection / modify our POJOs in such a way that the View is not able to modify the model.
Could YAGNI be applied to this request? We managed to give the responsibility of modifying the model entirely to the Controller, so I really don't understand why we should change our API just for the reason of restricting access to the Model even though we are not modifying it from the View anyway.
Also, since we are probably going to implement their request, what would be the best approach to complete the task? Making the View see a copy of the model classes so that every modification is pointless? Or maybe creating an interface that only exposes immutable objects to the View?
Thanks in advance for any clarification, we are a bit disoriented by this request.
Ideally, your View layer would only use immutable objects — not the same thing as unmodifiable interfaces to otherwise mutable objects — with the required info from your models. Such objects would be tracked by your Controller and then copied to the corresponding View. The MVC pattern can successfully model such scenario.
You will need to add another layer of indirection to solve your design problem (and still be MVC compliant). A possible solution follows:
Add a new interface with your view data model requirements:
/**
* This interface is adopted by an object that mediates
* the application’s data model for a SpaceView object.
*/
public interface SpaceViewDataSource {
List<Pawn> getPawns();
Card getCard()
...
}
In your View, store the current data source:
public class SpaceView {
private SpaceViewDataSource dataSource;
public void setDataSource(SpaceViewDataSource dataSource) {
this.dataSource = dataSource;
reloadData();
...
}
/** The data source has changed. */
public void reloadData() { ... }
...
}
Finally, your Controller should implement the SpaceViewDataSource interface and bind itself as SpaceView data source:
public class SomeController: SpaceViewDataSource, Observer {
private SpaceView spaceView;
private Space spaceModel;
private void configureSpaceView() {
spaceView.setDataSource(this);
spaceModel.addObserver(this);
...
}
List<Pawn> getPawns() { /* delegate to spaceModel */ }
Card getCard() { /* delegate to spaceModel */ }
void update(Observable o, Object arg) {
if (o == spaceModel) {
// A fine grained API may be required if
// this full reload doesn't perform well.
spaceView.reloadData();
}
...
}
...
}
In doing so, I added your Controller as a Space model observer as well.
All these refactorings puts you back on the MVC wagon, buying you:
a more reusable SpaceView component (no longer highly coupled with Space Model)
explicitly documented View data model requirements (the SpaceViewDataSource interface)
a View-Model communication that won't bypass the Controller layer
the Controller tracks the big picture, providing greater flexibility
I am developing an editor following the general MVC design: the model holds the data, the controller knows how to change it, and the view issues calls the controller to query and modify the model. For the sake of argument, let us use
public class Model {
public Object getStuff(String id);
public void setStuff(String id, Object value);
}
public interface Controller {
public void execute(Command command);
public void redo();
public void undo();
public void save();
public void load(File f);
}
The class that actually implements the controller holds a reference to the model; commands need to access it too, so they must all provide a void execute(Model m); interface that actually grants them this access only when needed.
However, views generally need access to the model - when building themselves and, later on, to listen for changes and refresh themselves accordingly. I am afraid that adding a "Model getModel()" call to the Controller will result in a great temptation to bypass the execute() mechanism; and I am not the only developer working on the project. Given this scenario, how would you enforce an "all changes go through the controller" policy?
Two alternatives I am considering:
An interface called "ReadOnlyModel", returned by the getModel() call instead of the real model, that catches any such attempts.
Lots of comments to clue incoming developers as to the Correct Way of Doing Things
I recommend modeling the access to the model as a set of classes. For example, if the view needs to modify a customer's attributes, there would be a ModifyCustomerCommand class that would have as properties all of the information needed in order to perform the update. The view would construct an instance of the class with values and pass it back to the controller which, in turn, would pass the command back to the model for the actual update.
A benefit from this approach is that each of these model access commands can implement undo behavior. If the controller keeps an ordered collection of these commands as they get sent back to the model, the controller can back off the changes, one at a time, by invoking the undo method on the most recently executed command.
What if you take a look at Observer Pattern http://en.wikipedia.org/wiki/Observer_pattern, your view only listen for events from model.
Hope it helps.
I am changing my application to use the MVC pattern. Currently in the notify() method for the observer I am sending the entire model to the View. Is this correct or should be be creating seperate Events and send them to the clients?
The Observable
public interface Observable<T> {
void notifyObservers(T model);
void addObserver(Observer<T> o);
void removeObserver(Observer<T> o);
void removeAllObservers();
}
The Observer
public interface Observer<T> {
void notify(T o);
}
The model sends notifications to view like this
#Override
public void notifyObservers(ModelViewInterface model) {
for(Observer<ModelViewInterface> o : this.observers)
o.notify(model);
}
And I notify them like this
notifyObservers(this);
In the ModelViewInterface I only have the getter methods (no setter methods) and my model implements this interface.
There are a few ways to do this sort of thing. For example, you could:
Send the model with every update, have the view replace its reference with every update.
This is ok, especially for a proof of concept. You may run into problems if you distribute your app across a network, as the messages become larger.
Send the delta with every update, have the view update itself based on this delta. This would have the benefit of smaller messages. On a distributed system this might work better, but you need to handle the local model maintenance in the view.
Dont send any of the model with updates to the view, but just tell the view that the model has changed and it should figure out what to do. On a distributed system, you could have the remote and local models work on keeping each other in sync, but the communication between the model and the view is very simple.
If I am using the MVP pattern with GWT, as in the GWT architecture best practices talk from Google I/O from 2009, but have spread out the information into multiple widgets, how should the value object be populated?
Say I have a EditPersonView/Presenter, a EditPetView/Presenter and an EditAddressView/Presenter and the last two are widgets as a part of a panel in the EditPersonView. With these I have the following class:
class PersonDetails {
private PetDetails pet;
private AddressDetails addressDetails;
// ...
}
The PetDetails and AddressDetails instance variables are managed in their presenter counterparts. When the user clicks the "Save" button in the EditPersonView, how should the communication between the widgets be done so that the PersonDetails is filled with information from its child widgets?
If you look at page 42 of the presentation by Ray Ryan from Google IO 2009 you should find the solution to your question. You use an "event bus" (shared instance of HandlerManager) and fire your custom PetDetailsChangedEvent event and listen for that event from your child widgets (page 45). Also, remember that while decoupling, etc is great and all, some coupling is not a bad thing and might actually be a better solution than trying to force everything to be loosely coupled - RR says so in that presentation himself :)
I've faced this same problem in a few different GWT applications that I've designed using Ray Ryan's approach.
My preferred solution is to create a Singleton "session object" that stores the state of that part of the application. In your example, it might look like this:
interface EditPersonSession {
void fetchPerson(PersonId id);
PersonDetails getCurrentPersonDetails();
void updatePersonDetail(PersonDetail<?> detail);
void updatePetDetail(PetDetail<?> detail);
void updateAddressDetail(AddressDetail<?> detail);
void save();
}
All three presenters contain a reference to the session object (perhaps injected by Gin). Whenever the UI (view) is manipulated by the user, the presenter associated with that view immediately pushes the state to the shared session object. For example, inside EditAddressPresenter:
view.getStreetNameTextBox().addValueChangeHandler(new ValueChangeHandler() {
void onValueChange(ValueChangeEvent<String> event) {
editPersonSession.updateAddressDetail(new StreetNameAddressDetail(event.getValue()));
}
}
When it is time to save, the state object is told to save the state to the server. At this point, the session object has up-to-date representations of the data, and can save it all at once. So, in EditPersonPresenter:
view.getSaveButton().addClickHandler(new ClickHandler() {
void onClick(ClickEvent event) {
editPersonSession.save();
}
}
This way, the presenters need not contain any references to each other, but can send consistent information to the server.
If the presenters need to know when information that they display has been updated (either by other presenters, or by the server), the session object can notify them by firing events on the event bus (shared Singleton HandlerManager). The presenters can then pull the most current PersonDetails from the session object.
I've also come to the conclusion that I can have one model that corresponds to each presenter. So a PetWidget may create a Pet instance and a PersonWidget may create a Person instance. The PersonWidget may then contain one or more PetWidgets which in turn means that the Person class can have a list of Pet instances.