Model-view-presenter pattern - 5 UI
Deprecated
This model-view-presenter pattern has been deprecated since Magnolia 6.0. It is part of the Magnolia 5 UI framework. For the updated implementation, see UI framework and development pattern changes in Magnolia 6 instead. |
Magnolia uses the model-view-presenter pattern. The separation of views and presenters is done consistently throughout the application on server and client and within complex components. The presenter reacts on events raised by user interaction, driving the view by populating it with data to display.
UI events
Magnolia uses a model-view-presenter pattern to handle UI events.
-
The View does not implement business logic or communicate with the Model. The view provides the interface to the end user and reacts on and informs the Presenter about user actions (input).
-
The View and Presenter communicate together.
-
The Presenter uses the Model to fetch data and implements business logic, informing the View to display content (such as a form).
-
The View interface defines a Listener interface that is implemented by the Presenter. The purpose of the Listener interface is to ensure that the view does not inadvertently communicate to the Presenter.
-
The Listener methods are implemented by the Presenter; the callback methods from the view to the Presenter.
-
The
Presenter
only knows about theView
’s Interface; this ensures that thePresenter
is not bypassing the pattern and cannot directly communicate to theView
implementation.
MVP and the app framework
Here we look at an example of how the MVP pattern is employed in a subapp.
-
The View’s interface defines an inline
Listener
interface with the methodgreetUser(String user)
.public interface HelloWorldMainSubAppView extends View { void setListener(Listener listener); void addUser(String user); public interface Listener { void greetUser(String user); } }
-
The Presenter (subclass) implements:
-
View
inline listener interface and thegreetUser(String user)
callback method. The method is called by the View (via the listener) on user input through the UI. -
The interface type of the View is determined by the
getView()
method. -
The Presenter
registers itself as theView
’s Listener using theonSubAppStart()
method. -
In the
onSubAppStart()`method the `Presenter
calls theView
’s interface `getView().addUser("Lisa")`method.//The Presenter implements the View's Listener by providing the View's callback method to the Presenter. public class HelloWorldMainSubApp extends BaseSubApp implements HelloWorldMainSubAppView.Listener { private LocationController locationController; // The View is injected into the Presenter's constructor. The View's implementation is defined by the IOC component provider. @Inject public HelloWorldMainSubApp(final SubAppContext subAppContext, HelloWorldMainSubAppView view, LocationController locationController) { super(subAppContext, view); // Set the location controller this.locationController = locationController; } // Defines the implementation of the injected view in use. @Override public HelloWorldMainSubAppView getView() { return (HelloWorldMainSubAppView) super.getView(); } @Override protected void onSubAppStart() { // Register this presenter as the View's Listener. getView().setListener(this); // Call the view to display something. getView().addUser("Lisa"); } // Implements the View's Listener method. Is the View's callback function to the presenter. @Override public void greetUser(String user) { // Do what ever logic needed triggered by this UI action. } }
-
-
View
calls thePresenter
via theListener’s
callback-functionlistener.greetUser(user):
@Override public void addUser(final String user) { Button button = new Button("Say hello to " + user + "!"); button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent event) { listener.greetUser(user); } }); layout.addComponent(button); }