Pure Model-View-Presenter on Android

Here we talk about finding the best Android mobile application architecture to relax our code and make it more testable and reusable.

It is quite complicated in the software development industry to find a standard of architecture in Android development. It is true that for some time a very basic MVP has been proposed to break the God object (activities that are responsible for absolutely everything) and not so long ago an MVVM has been proposed by Google with its architecture components adopted (ViewModel, LiveData, LifeCycleObserver). Although these architectures (especially MVVM) accomplish the objective of disconnecting components and making them reusable and testable, we still search a lot of points that make us wonder if this is the best architecture we can use.

In the first case, the presenter and the view are known, as well as the presenter and the model. Regarding MVVM, although ViewModel does not know the view, the view knows the ViewModel, which complicates reuse views with different ViewModels.

Read also: Intro to Mobile App Development

Pure Model-View-Presenter on Android

The dependency inversion principle (DIP) is respected only in one direction (view => service, and not service => view). This problem exists since an investment of dependencies in both directions gives us greater cohesion and less coupling, but also increases complexity. It is up to the reader to determine if this compensation is worth it.

In the case of classic MVP, for communication between layers, we find that this is done via callbacks (which will eventually turn our application into callback hell), while LiveVata is used in MVVM and although it allows us to avoid callbacks, it does not provide us with a large number of operators to manipulate data (at the time of writing this, we only have a map and switch map)

These are the main reasons that lead us to try to find a better solution when writing our applications.

Pure Model-View-Presenter or Controllerless Architecture

In our case, we opted for an architecture called Pure Model-View-Presenter (which we also usually label as architecture without a controller) that allows us to completely decouple the view of the model layer.

This is possible thanks to the presenter, whose only function is to associate a single view with a single application service (also called an interactor or use case); So that, to make the screen, we can use n presenters, one for each pair of view services

For example, we can understand our view and our service as black boxes that broadcast events and receive information (via input and output “cables”), and our presenter is responsible for connecting the input cables of one component to those of another’s output and vice versa.

By using lambdas for the display to communicate with the service, we can also model-View-Presenterrevent the Observables from being displayed directly under these components. In this way we can use RxJava in our service, so we can manipulate the data with all the operators that this library offers us, and LiveData in the part of the view that allows us to make an implementation that is aware of the changes in the life cycle of our activity, or even use the ViewModel provided by Google for that purpose.

View

In the case of Android, the implementation of our view corresponds to an activity or a fragment (fragment in the example/project that we have looked at), but it can be a ViewModel or even a visual component. The case that the display is an activity that is formed by N fragments is not discussed here, because each fragment will have M presenters and we can assume that the display would be any of those fragments, although they are then in one (or even fragmented in another).

Service

Our service will be responsible for applying all business logic and orchestrating the various domain services or directly, the repositories responsible for providing/storing information to/from the application.

Infrastructure layer

In the layer that is responsible for providing data to the application or storing the required layer (Gateway, BD, SharedPreferences, Cache …). Each of these communication channels will be implemented with a repository pattern that will be injected into the service where they are needed.

What Do We Win?

Thanks to the dependency service => view reversed, and not just the dependency view => service, we can do things such as:

  • Add/remove more listeners at runtime
  • At the same time, Use the same view with more than one “listener”.
  •  For example, when we need to communicate with the server with a click of a button and start a tracking event.
  • By debugging our application, we can see all event streams on one site, the presenter (s).
  • To implement the “presenter first” design before service and visual components, define two’s interfaces, such as methods and events

Testing

When we write tests for our application it is important that we can test isolated code units, which have no side effects in other parts of the application, and whose dependencies can be mocked (these code units do not depend on other parts of the Application). Due to the fact that in this architecture, our components are black boxes that receive events and deliver information, it is easy to verify that when you receive an X event, an information Y is issued.

The infrastructure layer (data) is also easily testable as all we need to do is mock the server’s response, and for that, we will use MockWebServer from OkHttp.

Where are we going?

Currently, there are architectures such as Redux and the Redux saga that operate under the principle of dependency investing, in the sense that they are completely Event-Driven.

Given the development of frontend architectures, it is not unreasonable to think that in Android we are approaching an architecture similar to Redux.

Improvements

For example, here this article Android training in Chandigarh discuss the several things that can be improved:

ViewModel: an extra layer can be added between the view and the presenter responsible for saving the status of the view. Moreover, this ViewModel can be injected directly into the XML with DataBinding and, with LiveData, connect the visual components to the LiveData Observables. It is also a challenge to investigate how this binding can be performed when dealing with an adapter.

Authentication: there is a limitation on the Github API where the same IP cannot make more than a certain number of calls (https://api.github.com/rate_limit) without authenticating a user; so adding basic authentication with OAuth2 via the Github site would be a good point to start improving this application

pagination: no paging mechanism is currently implemented, so the application shows no more than a certain number of results for a search query, so implementing a paging mechanism can be an interesting challenge in this architecture.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

Create your website with WordPress.com
Get started
%d bloggers like this: