Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply composition in android MVP?

Recently I took over an android project which is built on top of MVP. While simple screens are quite straight forward and easy to read and maintain, the more complex parts of the app are not. Multiple inheritance levels have caused me days of switching between classes, trying to find out how the information flow is actually working.

Here one example of the more problematic hierarchies:

inheritance

Since we use MVP, naturally there is another presenter class and another view class for each of the classes in the diagram.

So I did some research and found this article: Composition vs Inheritance in MVP and it's basically saying that composition should be favoured over inheritance in this situation. What it isn't saying is how to apply that in android. I thought about it for a while, but can't come up with a nice pattern. I could do custom views, but how would they use presenters in the end?

like image 655
stoefln Avatar asked Mar 16 '18 10:03

stoefln


2 Answers

Inheritance, although quite powerful, is quite easy to misuse, and when the inevitable happens, i.e change in requirements, inheritance is highly susceptible to break the open-closed principle due to its inflexibility. The programmer is bound to modify the existing classes which in turn breaks the client code. This is the reason why composition is usually favored over inheritance. It provides more flexibility with changing requirements.

This design principle says exactly that:

  • Encapsulate what varies. Identify the aspect of your code that varies and separate them from what stays the same. This way we can alter them without affecting the rest of the code.

Moving on to your problem, the first thing that came to my mind after I read your question was: Why not use Strategy Pattern!

The approach you can take is:

BaseMapViewFragment will contain all the code that is common to all derived classes. Have separate Interfaces for different kinds of behaviors(things that vary). You can create concrete behavior classes according to your requirements. Introduce those behavior interfaces as class fields of BaseMapViewFragment. Now classes that extend the BaseMapViewFragment will initialize the required behaviors with concrete behavior classes.

Whatever I said in the above paragraph might be confusing (my english isn't that good either :D), but I just explained the working of the Strategy pattern, nothing more.

There is another design principle at play here:

  • Program to an interface, not an implementation. The Strategy pattern uses it to implement the code that varies.
like image 53
Sarthak Mittal Avatar answered Nov 05 '22 00:11

Sarthak Mittal


I've been in a similar situation. What I ended up doing was taking out functionality from "Base" into separate classes then use it as composition. It was also related to using Maps in a similar structure.

You can create a new class MyAppMapView, it could extend a FrameLayout (or whatever best for your layout). This can contain all of your Map related code (including MapView), you can have custom MapView related functions here like onStart(), onResume(), onPause(), onStop(). Also, you can put everything related to maps here like markers, lines etc.

Once you have that in place you can just use new MyAppMapView() (or add it in xml using com.example.MyAppMapView) in your MapViewSimpleFragment and MapViewDetailsFragment and since both of these classes would be composing your custom MyAppMapView class, you can call all map related functions from Fragments like drawing markers, lines, onStart() etc.

like image 25
adnanyousafch Avatar answered Nov 05 '22 00:11

adnanyousafch