Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • The view primarily describes the layout of the UI and declares the handlers of the relevant user action events such as clicks, key presses and drag & drops.
  • The presenter acts as a delegate of the view when executing the business logic of user events, for example, when interacting with the back end / DB or fetching the data that needs to be displayed in the view. Normally, each view would use its own presenter and would not show it to the outside world. In some cases, when the view is simple enough, no presenter may be needed at all.
  • The model keeps the state of the view such as the current selection, the filters or toggles. Both the view and the presenter may have access to the model and may mutate it arbitrarily. However, when it comes to modifications done by the presenter, it is important to resolve synchronization of such view changes.

...

In the case of Magnolia, where flexibility is very important, MVP opens up possibilities to augment or customize the UI by overriding only one element of the triadthree elements.

MVP in the Magnolia UI framework

...

  • Using definitions: the user interface should be as configurable as possible so that all MVP triads elements would consume a definition (form, dialog or content view) and produce a UI component.
  • Keeping views back-end-agnostic as much as possible: the business logic related to the back end, in most cases to JCR, should be replaceable with similar implementations for other back ends. This typically boils down to overriding a presenter.
  • Reusability: we want to let the developers use the parts of our UI in various custom contexts and compositions.

...

  • Let it consume the definition.
  • Build a view based on it.
  • Produce child presenters, if any.
  • Have these child presenters generate their views and attach them to the view. 

In this presenter-centric approach, the following can be observed:

  • A presenter typically has a start(...) method with the definitions, the event bus and the initial state as input: 
    TreeView TreePresenter#start(workbenchDefinition, eventBus, viewTypeName, contentConnector)
    Besides being bulky and slightly confusing, these methods need to be called externally, forcing the lifecycle of a particular view/presenter to be managed outside. For example, a workbench has to call the start methods of TreePresenter and ListPresenter; otherwise, they would not be populated properly.
  • A view typically interacts with a presenter over listener-like interfaces, which results in additional boilerplate code. In other words, after creating a view, a presenter would subscribe to view events as an observer.
  • A parent presenter is aware of the sub-presenters. Moreover, it has access to the sub-views, which adds too much responsibility to it.
  • Component composition takes place at the presenter level. This is counter-intuitive compared to composition happening at the view level since views are essentially synonymous with components.
  • View state is managed by the presenter and is shared primarily via events, causing synchronization to be a problem—effectively, only notifications (messages) about the changes are sent, after which every part of the UI involved finds it difficult to store the current state.

...