6

I have a Presenter ( RoomPresenter) and a Model ( RoomModel). My RoomModel have some methods like:

  1. void createRoom(RoomData roomData, List<User> users)
  2. void addUsersToRoom(int roomId, List<User> users)
  3. void joinRoom(int roomId)

This is the createRoom() implementation:

void createRoom(RoomData roomData, List<User> users) {

    addUsersToRoom(roomData.getId(),users);
    joinRoom(roomData.getId());
}

So, when the user wants to create a room, ( abstracting the View -> Presenter methods call) the presenter will call the createRoom() method of the RoomModel.

My question is: Would be a good practice make the presenter, and not the model,implement the createRoom method? (i.e. the presenter will have the createRoom() and the model will have just the addUsersToRoom() and joinRoom() methods). Because in that way, I'll be able to call some View methods (e.g. show a toast or a loading status) before or after calling the addUsersToRoom() and joinRoom() methods.

  • @RobertHarvey, the createRoom don't create any UI element, it creates a Room object. – Rômulo.Edu Mar 20 '16 at 2:52
  • Perhaps the name createRoom is somewhat inappropriate if you want it to also trigger something in your View. Are you intending to tie createRoom into a specific button press (or other input command) on your View? If so, perhaps onCreateRoomButtonPressed makes more sense? – Ben Cottrell Mar 20 '16 at 14:26
  • @BenCottrell yes! If I made the presenter implement the createRoom(), I would rename the method to onCreateRoomButtonPressed() because it would make much more sense since we're talking about the Presenter. – Rômulo.Edu Mar 20 '16 at 14:33
5

The method could be part of the presenter, it could stay in the model, or it could be moved to a separate helper or controller class. None of these placements is always "better" or "best practice". Which to choose depends on factors like how complex is that operation, does it only make sense in conjunction with those view/presenter operations, do you want it to be unit testable, or how do you organize responsibilities between the layers in your program? For example, the method could look like this:

 void createRoom(RoomData roomData, List<User> users) 
 {
     sendEventBeforeCreateRoom();
     addUsersToRoom(roomData.getId(),users);
     sendEventUsersAdded();
     joinRoom(roomData.getId());
     sendEventRoomCreated();
 }

The catch here is what those "sendEvent" methods are:

  • If the method is in the model, you need them to be event firing methods, and so you need an event mechanism in your model layer.

  • If you do not want the latter, or if the method in reality is so complex it justifies a class of its own, you could put it into separate controller, and classes like the presenter have to subscribe to those events first. This makes the code more complex, but the benefit is you can now test it easier in isolation.

  • If you place the method in the presenter, the "sendEvent" methods could be replaced by direct calls to corresponding methods of the presenter. That is the simplest approach, but it gives you less flexibility for testing or reusing the method in a different context

So pick your choice on what kind of flexibility you need (but do not add any flexibility "just in case"). If it turns out you do not really need that sendEvent methods, keeping the method in the model would have been probably the most simple and therefore best choice.

4

Leave createRoom in the model. Throw MVP out the window for a minute, and look at this list: {createRoom, displayRoomToUser, addUsersToRoom, joinRoom}.

Which method isn't like the others? Obviously displayRoomToUser doesn't belong. However, the other 3 "seem" like they all belong together. If you were making a class, it seems logical that these 3 methods would all belong to the same class.

Try to find a way to enable the functionality you seek while following the spirit of the paradigm, rather than forcing the paradigm to accommodate your coding style. Often times there is an elegant solution.

1

About your question:

In the MVP pattern the presenter is responsible for binding the view and model. It is responsible to cope with interactions issued by the view and to select data from the model and to issue commands to the model.

Under this perspective, your question could be reformulated:

  • "Does createRoom represents an interaction that just combines addUsersToRoom and JoinRoom ?" - Then it's perfectly valid to move it to the presenter.
  • "Or does it as well change something else in the model ?" - It should then remain in the model and it would be a bad practice to move it to the presenter.

About your real need

Regardless of the answer, your concern seems to be the call of view methods to reflect the basic model changes (such as joinRoom and AddUsersToRoom). This is not directly related to createRoom, as the other changes could be triggered directly anyways.

You should organize a notification of the view for the events of relevant changes in the model. The view should subscribe to these event notifications (i.e. observer pattern) via the Presenter. Notification can be implemented via presenter or directly from the model, depending on the variation of the MVP pattern that you use.

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.