Model-View-Presenter and Android Application Design - android

The Problem: Really large and convoluted Activity classes. Hard to read/understand and modify. Hard to test.
The Possible Solution: Model-View-Presenter (perhaps with dependency injection).
And Mock Test Objects!
I'm planning on implementing Model-View-Presenter in my Android application.
This is basically a variant of the Model-View-Controller. In essence, make the Activity
a glorified layout manager and defer any business logic to the Presenter. Another way of looking at the Presenter is that its like an Helper class instantiated within an Activity to do the heavy lifting with the activity providing a interface/callback that the Presenter can use.
I would like to get some community thoughts on this. For example:
What interfaces are implied by this?
What responsibilities would the Model and View have vs. the Presenter.
For Presenter I suppose the Activity would implement the interfaces needed by the Presenter?
What kinds of things should go into the Presenter vs. Activity?
Would a presenter be one-to-one with an Activity? What about an Activity with multiple fragments displaying different widgets each with its own adapter? Do we now need multiple presenters or still just one?
What about Presenter vs. Adapter?
How should a presenter relate to say an Activity with a ListView and a ListViewAdapter?
What goes into the Presenter vs. Adapter?
Should the Presenter pick the Adapter to use? Or should the Activity make this decision?
Should the Presenter process Model Data or the Adapter? Is there a conflict between adapters and presenters? Are adapters presenters? or something less/more. Usually Adapters are just for widgets like ListViews within an Activity. They don't make the calls that get the data itself I think.
So in model-view-presenter the key thing is really to decides what goes in the presenter vs. other classes and what the communication should be between the presenter and activities, adapters and views/including fragments.
Is Model-View-Presenter just a really bad idea for Android? Or does it fit well with the Android Framework?
Keep in mind there are numerous examples outside Android of very mature SDK's that still needed a micro-architecture like MVP. In fact examples abound: eg. Flex was very mature SDK for Flash and yet it still needed MVP and MVC frameworks for almost any major app.
EJB needed Spring to simplify and organize it. MFC/Struts etc and the list goes on and on. Why should Android be any different? Why should we assume the SDK has everything needed in the case of Android without a design pattern like MVP?
Nice to know before I spend hundreds of hours on this, please feel free to comment/answer on any part of this question.

Android punishes poor MV(P|C) design more than any platform I've ever encountered. Forget the clumsy methods it provides for passing state up and down the activity stack. Get as much state and logic out of your activities as possible. Move it into Services, ContentProviders, and SharedPreferences as appropriate. Try to make your activities pure view. IMO, Services have never been given enough attention in Android tutorials. Even the O'Reilly Programming Android book only gives them a quarter page!
Be wary of extending Application. If you ever start a Service in its own process (e.g., to allow it to be shut down gracefully when an Activity crashes) then the Service will have its own copy of your Application.

Just to provide a reference for others who may be interested. I was thinking the same thing some years before. When we apply MVC/MVVM/Presentation Model to android app, what we really want is to have a clear structured project and more importantly easier for unit tests. At the moment, without an third party framework, you usually have lots of code(like addXXListener(), findViewById()...), which does not add any business value. What's more, you have to run android unit tests instead of normal JUnit tests, which take ages to run and make unit tests somewhat impractical. For these reasons, some years ago we started an open source project RoboBinding - A data-binding Presentation Model framework for the Android platform. RoboBinding helps you write UI code that is easier to read, test and maintain. RoboBinding removes the need of unneccessary code like addXXListener or so, and shifts UI logic to Presentation Model, which is a pojo and can be tested via normal JUnit tests. RoboBinding itself comes with more than 300 JUnit tests to ensure its quality. Other alternatives: Android-Binding, Bindroid and MvvmCross.

Related

Should I use ViewModel with UseCase?

This is more of a question about designing applications, rather than fixing a specific issue.
So most Android tutorials I see use ViewModel as a layer between the data source and the views. Hence my first impression was that a ViewModel is supposed to handle data fetching and updating, but then I read about 'Use cases' which most Android samples don't even mention and I don't understand how all these parts fit together. What's the relationship between a ViewModel and a use case?
1) Clean Architecture this is approach how to design your application. This is not about specific realization like in case of ViewModel.
2) If you looked at the official Android documentation you will not find any mentions of Clean Architecture. Google not forcing this approach.
3) ViewModel this is part of MVVM design pattern. So if we looking info Clean Architecture MMVM can be part of Presentation layer (same as MVP commonly used in this layer). But you still need UseCase to make interactions between Data layer and Presentation layer.

Is it correct to bind a ViewModel to a Service?

I've started using Architecture Components in my application and I'm still learning how to use it.
In my app I have an Activity showing different Fragments sequentially. In some of them I need to communicate with a background service in order to receive data from external BLE sensors. Since I need to interact with the service in more than one Fragment, I'm wondering if ViewModel is the right place where to make the binding. I've looked around but I didn't found an answer.
Are there any problems binding a service inside a ViewModel?
It is not advisable to use Android framework classes inside ViewModels.
Here is the link on Google Developers blog post with the detailed explanation: ViewModels and LiveData: Patterns + AntiPatterns
Ideally, ViewModels shouldn’t know anything about Android. This
improves testability, leak safety and modularity. A general rule of
thumb is to make sure there are no android.* imports in your
ViewModels (with exceptions like android.arch.*). The same applies to
presenters.
Don’t let ViewModels (and Presenters) know about Android framework
classes

MVP Implementation in Android

I am looking into MVP architecture Implementation in android.
I found too many ways(mention end of the question) to implement it in the android studio, but Still, I am confused.
Can someone help me to find the right answer of below questions.
What would be directory structure of Application in MVP?
Activity should be a Presenter or View?
Way-1
Way-2
What would be directory structure of Application in MVP?
There is no predefined structure for that. What makes your code readable or what structure you are following, you can use same for MVP also.
Activity should be a Presenter or View?
View is the UI layer which displays the data and notifies the Presenter about user actions. So Activity will always be a view.
If you are looking for a good example of MVP implementation, there is one GitHub Repo for MVP developed by Android itself. Which you should look into.
Where
todo‑mvp
Demonstrates a basic Model‑View‑Presenter (MVP) architecture and provides a foundation on which the other samples are built. This sample also acts as a reference point for comparing and contrasting the other samples in this project.
todo‑mvp‑clean
Uses concepts from Clean Architecture.
todo‑mvp‑dagger
Uses Dagger 2 to add support for dependency injection.
todo‑mvp‑rxjava
Uses RxJava 2 to implement concurrency, and abstract the data layer.
todo‑mvvm‑databinding
Based on the todo-databinding sample, this version incorporates the Model‑View‑ViewModel pattern.
todo‑mvvm‑live
Uses ViewModels and LiveData from Architecture Components and the Data Binding library with an MVVM architecture.
Though there are lot of implementations for an MVP architecture, all of them share a basic idea (or they should at least), which is separating business logic from your views (activities, fragments, dialogs). Why is that? Well, for two reasons mainly:
separation of concerns
Testability: your business logic is able to be tested if there is no android components involved.
About your questions:
What would be directory structure of Application in MVP?
There is no rule about that except that your MVP components should be identified. Here you have an article where I started with a package structure but then I found other more convenient.
Activity should be a Presenter or View?
Your activity (or fragment or whatever components in charge of showing view components) should be the one that implements your view.
My advice is that you should check multiples examples and see their advantages and disadvantages of each one, and try to define your own architecture from those which you will feel more comfortable with.
You can use either Activity or Fragment for View layer. This is because showing UI elements in android needs Context.
For the Presenter layer, you must make sure not to pass the Context to the Presenter via constructor or setter. If you needed Context in your Presenter for tasks other than showing the UI, such as writing to SharedPreferences, you can get it from your View (which is either Activity or Fragment). In this way, if the View gets destroyed or becomes null, there would no standalone null Context in the Presenter to cause leak issues.
If you want to know more about the MVP structure, I have written a very handy MVP library for android and explained its use in a sample app here.
MVP android sample example application
MVP Android Example used to explain how to use this pattern in our Android apps.

Trying to fit a "clean architecture" on an iOS app

Recently I’ve been rethinking my android architecture project, trying to adapt it to a more “clean architecture”, specifically, the kind of design suggested by “Uncle Bob”.
Which it involves several layers of abstractions, a nice isolation of responsibilities and a very strong dependency inversion achieved by dependency injection; which, ultimately, leads to a very decoupled-portable system. A perfect candidate to be tested by unit testing and integration testing.
In my android implementation I’ve ended up having three different modules or layers:
-domain: entities, interactors, presenters (pure java module)
-data: (acts as a repository to supply the data to the domain) (android library module)
-presentation: ui related stuff, fragments, activities, views, etc (android application module)
So, I’m trying to figure out what would be the best approach on the iOS ecosystem.
I’ve tried creating a project with multiple targets to achieve the same solution:
-domain: command line target (which seems very weird but I think is the most pure swift target available)
-data: cocoa touch framework
-presentation: cocoa touch framework
With this approach I can use these targets in the way I did with android modules. But the first caveat I’ve found it is that I need to add manually every new file to the dependent target.
But my knowledge is very limited in projects with multiple targets. I mean I’ve never created an iOS application with multiple targets. So I don’t know even if the solution would be use a framework (cocoa touch/cocoa) as a target instead of a command line module for the domain layer.
Any thought would be really appreciate.
Thanks!
Uncle Bob's Clean Architecture absolutely applies to iOS, Swift, and Obj-C. Architecture is language agnostic. Uncle Bob himself codes mostly in Java but in his talks he rarely mentions Java. All his slides do not even show any code. It is an architecture meant to be applied to any project.
Why am I so sure? Because I've studied MVC, MVVM, ReactiveCocoa, and Clean Architecture for 2 years. I like Clean Architecture the best, by far. I tested it by converting 7 Apple sample projects to using the Clean Architecture. I've used this approach exclusively for over a year. It works out better every time.
Some of the benefits are:
Find and fix bugs faster and easier.
Extract business logic from view controllers into interactors.
Extract presentation logic from view controllers into presenters.
Change existing behaviors with confidence with fast and maintainable unit tests.
Write shorter methods with single responsibility.
Decouple class dependencies with clear established boundaries.
We also added a router component so we can use multiple storyboards. No more conflicts.
Writing unit tests is greatly simplified too because I only need to test the methods at the boundaries. I don't need to test private methods. On top of that, I didn't even need any mocking framework because writing your own mocks and stubs becomes trivial.
I've written my experience for my last 2 years studying iOS architecture at Clean Swift I also put together some Xcode templates to generate all the Clean Architecture components to save a ton of time.
UPDATE - To answer #Víctor Albertos's question about dependency injection in the comment below.
This is a really great question and demands a long detailed answer.
Always keep the VIP cycle in mind. In this case, the doSomethingOnLoad() method is not a boundary method. Rather, it is an internal method invoked only within CreateOrderViewController. In unit testing, we test a unit's expected behavior. We give inputs, observe outputs, then compare the outputs with our expectations.
Yes, I could have made doSomethingOnLoad() a private method. But I chose not to. One of the goals of Swift is to make it easy for developers to write code. All the boundary methods are already listed in the input and output protocols. There is really no need to litter the class with extraneous private modifiers.
Now, we do need to test this behavior of "The CreateOrderViewController should do something on load with this request data" somehow, right? How do we test this if we can't invoke doSomethingOnLoad() because it is a private method? You call viewDidLoad(). The viewDidLoad() method is a boundary method. Which boundary? The boundary between the user and view controller! The user did something to the device to make it load another screen. So how do we invoke viewDidLoad() then? You do it like this:
let bundle = NSBundle(forClass: self.dynamicType)
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
let createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController
let view = createOrderViewController.view
Simply calling the createOrderViewController.view property will cause viewDidLoad() to be invoked. I learned this trick a long time ago from someone. But Natasha The Robot also recently mentioned it too.
When we decide what to test, it is very important to only test the boundary methods. If we test every method of a class, the tests become extremely fragile. Every change we make to the code will break many, many tests. A lot of people give up because of this.
Or, think about it this way. When you ask how to mock CreateOrderRequest, first ask if doSomethingOnLoad() is a boundary method that you should write test for. If not, what is? The boundary method is actually viewDidLoad() in this case. The input is "when this view loads." The output is "call this method with this request object."
This is another benefit of using Clean Swift. All your boundary methods are listed at the top of the file under explicitly named protocols CreateOrderViewControllerInput and CreateOrderViewControllerOutput. You don't need to look elsewhere!
Think about what happens if you were to test doSomethingOnLoad(). You mock the request object, then assert that it equals to your expected request object. You are mocking something and comparing it. It's like assert(1, 1) instead of var a=1; assert(a, 1). What's the point? Too many tests. Too fragile.
Now, there is a time when you do mock CreateOrderRequest. After you've verified the correct CreateOrderRequest can be generated by the view controller component. When you test CreateOrderInteractor's doSomething() boundary method, you then mock CreateOrderRequest using interface dependency injection.
In short, unit testing is not about testing every unit of a class. It is about testing the class as a unit.
It is a mindset shift.
Hope that helps!
I have 3 series of draft posts in Wordpress on different topics:
In-depth look at each of the Clean Swift components
How to break up complex business logic into workers and service objects.
Writing tests in Clean Swift iOS architecture
Which one of these do you want to hear more first? Should I bump up the series on testing?
In my opinion Clean Architecture is a set of ideas, rules, principles... to make a code better.
[Android Clean Architecture]
With this approach I can use these targets in the way I did with android modules.
You are able create a target[About](application target or framework target...) but it depends on your needs
If you read Architecting Android...Reloaded from Fernando Cejas
you might have seen that I used android modules for representing each layer involved in the architecture.
A recurring question in discussions was: Why? The answer is simple… Wrong technical decision
The idea is that is not necessary to use some build components to implement Clean Architecture

Benifits of implementing MVC in Android

I want to implement MVC in my Android application for reasons I have heard but not realized. Can anyone lead me to implement MVC in my application? Kindly mention the benefits for using the same.
Thanks
The key benefit of MVC (and its variations) in general and not only for Android is separation of concerns. This means you keep business logic isolated in the Model instead of mingled with the presentation logic. In turn the Model becomes easier to unit test, modify, and reuse (when reuse is a concern at least).
I'm not sure if there is much sense in testing the View or Controller parts of MVC. The View for one thing is supposed to be as much 'dumb' as possible, to the point of lacking even presentation logic.
MVC apparently has trouble telling where the presentation logic belongs to -- this seems to be the reason why MVP has been created, so all this logic goes to the Presenter. So by using MVP instead of MVC you would also have the benefit of easily testable presentation logic.
MVC also allows (in theory at least) to change the user interface adopted by the application, though I'm not sure how this applies to Android (maybe for games?).
Needless to say, Android apps DO NOT implement MVC by design. Otherwise those benefits would be available to Android apps by design, which is not true.
It's already implemented as per this post here: MVC pattern on Android
For one thing, it allows you to plug in a different algorithms or data store/source into your app with a single line of code. So in my sample Android app, I can switch from DES, to AES to TDES encryption in one line of code. It allows you to port your algorithm to another app with a completely different user interface and architecture. So in .NET I can write a Windows Form app and then port it to a Web Form app without re writing the core algorithm code. If you are looking for an example in Android I have a complete example here. If you can read C# code I have an example here.
Have fun.
JAL
Java has very powerful features behind it. The word MVC means at the bottom line, basically, componentization. Components are a very important definition in a OOP language like Java, and even more important to languages that implement memory allocation and handling like Java with the GC (Garbage Collector).
There's lots of GC algorithms & types implemented out there, each JVM has it's own number of sets, Oracle has it's own, IBM, Apache's OpenJDK, and so on and on. But the concept is almost every time the same: reference counting. Let's picture an example where you have an object A, that define a property of type B, and this class B has also a property to another class called C, and they are all in the same processing scope (e.g. a method). Analysing this example, the runtime (JVM) could only release "B" after "C" is out of scope (out scoped), and also "A" could not be liberated because of "B" being used by the same scope. Putting this in perspective, the scope modifiers, methods, classes, static methods and classes, final declarations, everything needs to be carefuly chosen.
Summing all together, that means not only you get a more well organised code using patterns like MVC, but also more performance in the JVM runtime, because depending on the size of your program, your GC pool can really be a bottom-neck, and fine grained java code, with methods with a just few lines divided by a few number of classes, will always perform better. Huge classes, with just a few methods with a lot of lines of code within, tend to perform poorly.
... and that's the beauty of things. MVC not only gives a more well organised code, but also, more performance. Hope it helps!

Categories

Resources