Question

We work in a Java shop here and our web application uses an implementation of the MVP architectural pattern. Our manager comes from a .NET world, where he has been exposed to the MVVM design pattern. Our manager is advocating changes in our MVP implementation, including that the Presenters should be decoupled from (or loosely coupled to, depending on your interpretation) its Views via the Observer design pattern, in tradition with MVVM. I am more of the opinion that the Presenter and the View work together to achieve a common goal, and as such should be coupled.

Among the arguments brought up in support of the change is the ability to unit test Presenters. If the Presenters only see the views as Observers, the argument goes, then they can be more easily unit tested. But presenters strongly coupled to their views are not necessarily difficult to test. If the View uses the Humble View paradigm, then it can be mocked. And finally, testability should be a symptom of good design, not a driver for the design.

Another argument used by my manager in support of layering the Views and the Presenters is the supposed maturity of MVVM. As such, we should follow MVVM's teachings and adapt to its implementation of MVP. Correct me if I'm wrong, but MVVM imposes the (artificial) layering of views and presenters in order to facilitate its data bindings in controls.

Can you please help us see the light here? Why should we use a decoupled model and pay the price for it? I'm not seeing the benefit. Occam's razor says I need arguments to use decoupling, and testing doesn't seem to be one of them.


Clarification: What I'm really looking for with this question are the arguments that can tip the balance in favor of a presenter that doesn't know about its view and shoots events in the aether or in favor of a presenter that knows about its view(s) through more direct coupling, like a humble view interface or directly to the class. Note that presenters can easily serve multiple views with both loose and tight coupling. The difference is in the interface that the presenter talks to: with loose coupling, the presenter talks to listener classes (or an event bus representative), whereas with tight coupling, the presenter talks to the view interface.

Was it helpful?

Solution

UPDATE:

Looks like the TS does not asking whether to pass interface instead of class to the presenter, but whether the presenter are communicating to the view via another layer (let's call observable). It is simply try to reflect MVVM pattern used in WPF for the view management. If that's the case then all of my arguments before are invalid.

Personally, I think that the approach is bad and does not give many benefits instead of cons. Here is the points I would like to mention:

  1. Humble view is already enough for maintainability

    As stated by the TS, humble view already sufficient for creating testable classes and modular enough for separation of concern / responsibility. You can see the revision of my answer stated that humble view is already maintainable.

  2. It added complexity and learning curve

    Unless your approach are supported by built-in distributed library such as WPF, then you are in doom for learning the approach. It is not common and new developers will find it hard to learn your design.

  3. It reduces code discoverability

    My experience with WPF is that without proper agreement in folder structure you will find it hard to discover the presenter (because it will refer to observable). WPF have some guidelines with folder structure (called conventions) so new developers which understand WPF will understand it.

  4. Harder to debug

    If the binding (listening point) is declared mistakenly, you will get a hard time finding the mistake. Most of the times the mistake gives you wrong exception. Even in WPF, newcomers will find hard to debug.

  5. Harder to ensure property update and more risk for infinite cycle

    During developing WPF I find it hard to ensure property update between the view and presenter (viewmodel). MVVM design which listen to changes such as Knockout and WPF have higher risk of infinite cycle occuring (change in prop A updates prop B which updates prop A and so on).

  6. You baypassed the compiler validation

    What I don't like with WPF / MVVM is that the compiler cannot help validate your binding. It means that null reference and data type error can only be handled in runtime level.

  7. It is not implementable to web apps.

    The observable layer may be useful in event-driven apps such as desktop app or even mobile app. However in web apps which structure based on Request -> Response it is just a useless layer of abstraction. I have yet found any presenter logic which can be used in both web and apps architecture. If it will be duplicated anyway, why not make it more simpler? Moreover Humble View approach may be used (not perfectly, but can) in web architecture.

  8. You will need BLL anyway

    No matter what architecture you build, you still only handle the code in PL level only. You will still need BLL in another layer to ensure the business logic can be reused no matter what the UI is (web / desktop).

  9. The benefit is just another layer of separation

    I don't know what you want to approach in java. However in WPF I find it is easier and safer (in terms of not breaking the viewmodel / presenter) to modify the view.

Summary:

With MVP using observable, you violate KISS / YAGNI. If you does not use distributed library, you also violate Reinvent the Wheel. The only benefit is to support for DRY (to manage data binding) but since it cannot be used in web structure, the benefit is not worth it.

OTHER TIPS

You and/or your manager may be confusing dependency direction and coupling tightness.

The essential difference between MVVM and (Passive View) MVP is that in the former, thanks to bindings and commands, the ViewModel basically has no knowledge of the View. The dependency goes from View to ViewModel. In Passive View MVP, it goes the other way - the Presenter points to the View, populating its data and listening to its events.

It does not need to be a tight coupling though - you can couple the Presenter to an abstraction of a View which can be embodied by a mock in a test context. This is loose coupling.

That being said, I agree with you that both patterns (MVVM and Passive/Humble View) are roughly equally testable. Plus, MVVM is essentially valid in a .Net environment where you can leverage bindings and commands, which makes that specific pattern a strange call in a Java ecosystem. Similar approaches may exist in the Java world, but they aren't called MVVM.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top