6

I'm learning the MV* patterns. MVP in this case. I'm trying to refactor an old android application into the MVP pattern to make things less tightly coupled, but I'm struggling one one concept. I know that the presenter get's data from the domain layer which connects through the data layer, but how can the view communicate with the data, directly or indirectly? here's an example of what I'm trying to figure out:

I've got a long running download service (I assume this should be in the data layer) that needs to be started or stopped depending on user interaction in the UI. How would I communicate those signals to the service in the data layer? should I do that through the domain layer?

from what I've seen it looks like the UI can not talk back to the data or domain layers.

If someone would be willing to explain this to me I'd be very grateful.

here are some of the articles I'm working off of: first resource | second resource | third resource

7

In the MVP pattern is the View is "dumb". It doesn't really do anything. The presenter acts as the controlling object in the heirarchy, while the Model stores the data and has business logic methods on it.

That doesn't preclude the View from firing events, which are hooked by the Presenter to methods or properties on the model, or to other testable logic on the Presenter itself.

Your presenter has access to both the model and the view. On your presenter you can therefore hook up events fired on the View to methods or properties on the Model. The view and the model never know anything about each other.

  • 1
    In this case the data layer (model) has some capacity ( a function ) to start and stop. In an monolithic app, you may want to call this function from the UI. But if you understand the architectural principle, you should create a 'general' command in the Model, that is like "StartDownload", "StopDownload". Then maybe later, you can add some code in those methods, that will generate a message, stating how much of the download is completed. Or, for example, let's say your data layer (Model) changes to a different OS. you only have to change the 'general' code. Your View is safe. – Andyz Smith May 20 '15 at 12:05
  • Or even better, even time you get a call to 'GeneralStartDownload' the Model can contact the Controller and see if that person has JavaScript enabled or whether it is on a Slow Connection or a Fast Connection and decide whether to add an OnLoad to the next postback to Pop-Up the Download percentage. This is all Controller'ed. So the logic is in the one place. not scattered throughout the Model (which may change based on the OS, yah? right...) or the View, which maybe in different GUI language next year.....the controller code lives on.... – Andyz Smith May 20 '15 at 12:19
  • @stephen, can you throw some light on how should one communicate from model to presenter so that presenter could perform some action on view. for eg, say, database read is done in model then, how should model tell to presenter that it has read the data and pass back the data to presenter so that presenter could update view – eRaisedToX May 25 '17 at 6:16
  • The presenter can subscribe to events on the model (observer pattern). – Stephen May 26 '17 at 4:48
3

In both MVP flavours, Passive View and Supervising Controller, the presenter handles the input logic and other complex view logic. So the download control logic should definitely go into the presenter.

In a typical Java setting (I assume Android is similar), you can register event handlers with the widgets. So you can pass the interaction from the view to the presenter in two ways:

  1. The presenter registers itself as event handler to the widget. This requires either direct access from the presenter to the widget (not so good for loose coupling) or a public method on the view. I see this as a bit cumbersome.

  2. Register an anonymous event handler within the view class and call a presenter method to further handle the event. This is my preferred way. Some pseudo-code:

    downloadStopButton.addSelectionHandler(new Selectionhandler() {
        handleEvent(Event e) {
            presenter.downloadStopCalled();
        }
    });
    

In both cases, the presenter then instructs the model or service layer to stop the download. If you have some state related to the download in a model, and the model knows about the service, then you can go through the model. Otherwise I think just calling a service from the presenter is also ok.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.