0

I am trying to implement MVP architecture using google sample code for mvp. I have an activity as View that has a presenter and model. On button click user can capture and save image in external storage. And on capture click, I also need to play a sound.

I am not sure which code should be put in which class because I cannot put camera capture and play sound code in Activity (which I treat as view) to keep the view as dumb as possible and I cannot put that code in Presenter because it uses Android framework classes (context etc).

So, the only option is to put it in model but in sample code, model only has Repositories (that I believe is relevant to data sources only local/remote).

How to put this code in model and how to link it with other components like View and Presenter? Any guidelines?

muzaffar
  • 1,706
  • 1
  • 15
  • 28
Nouman Bhatti
  • 1,777
  • 4
  • 28
  • 55

1 Answers1

1

Here's one way you can go about solving an issue like that.

Your problem is that some code makes sense to go into a presenter, however it's too Androidy, so you can simply interface around it.

What you basically need is two things that can do certain functions.

interface CapturingSoundPlayer {
    void playSound();
}

interface ImageCapturer {
    void captureImage();
}

Please note that names and method signatures are up to you and what you need, I am merely using them to make a point.

Now it's perfectly safe for your application to have those two interfaces as dependencies, they have nothing to do with Android, we have simply take then technology out of the equation and only left the behaviour.

You need to pass these dependencies to your presenter and use them whenever needed.

class Presenter {
    private final CapturingSoundPlayer soundPlayer;
    private final ImageCapturer capturer;

    Presenter(CapturingSoundPlayer soundPlayer, ImageCapturer capturer) {
        this.soundPlayer = soundPlayer;
        this.capturer = capturer;
    }

    void onCaptureButtonClicked() {
        soundPlayer.playSound();
        capturer.captureImage();
    }
}

Now the implementation for those interfaces can be completely separate from your Activity, making your view still stupid.

Those interfaces (and their implementation) are simply logical units/entities that your presenter uses to split up the logic. I simply think of the functions of "capture" and "playSound" as simple actions, just like view.showLoading, and your presenter plays an orchestrator, it uses "something" to manipulate the view, which is the view interface, and it uses something else to manipulate sound, which is the interface for doing that.

if repositories are considered to be data sources, then in my opinion those helpers don't fit under that definition.

If you have a utility to retrieve the images that has been captured, that would basically can be considered as a repo for your images, but simply taking an image, is just another action.

You can structure/organise them as you feel fit, but just because you are using MVP, not every class you create has to be either one of those letters (M/V/P).

Sometimes any of those layers will need classes that logical units to do something, so that you have better separation of concerns.

Consider you have quite complex formatting logic, it would make sense to separate that in a separate class other than the presenter, but does that mean that the separate class is now model? It could, but it doesn't have to be.

elmorabea
  • 3,243
  • 1
  • 14
  • 20
  • Thanks for the response. But i am still confused about the model/repository part of it maybe i am too newbie. Can you please elaborate where should i implement these Interfaces like the actual code for capture and mediaplayer. Should that code be in model? If yes then isn't the model only for Repositories like data sources (http/db). Should i make a CameraRepository and implement these interfaces over there? – Nouman Bhatti Dec 11 '17 at 15:55
  • I have updated answer, because it was a bit too big for a comment :D – elmorabea Dec 11 '17 at 16:04
  • so i can create a helper class to capture and play sound. Which means presenter is not bound to interact only with model to do something it can also interact with other Helper classes. I think i got too bounded by mvp. I got your point. Regards – Nouman Bhatti Dec 11 '17 at 16:24
  • You sure can! and you'll find that unit testing your helpers in isolation will be easier, also will make nice small presenter/view classes. – elmorabea Dec 11 '17 at 16:26