M — Model in MVC, MVP, MVVC in Android

Hello, dear reader, hope you are Android Developer.

Android Fragments in trouble last year, more and more developers talking about their problems and guys from Square (as always) have a solution — Flow and Mortar.

Today I found my old comment to “Advocating Against Android Fragments

https://twitter.com/artem_zin/status/570191985623085056

I found it because I’ve read post from Android Weekly: “An Investigation into Flow and Mortar”.

I won’t talk about Flow and Mortar (just read manuals, posts and try them). I want to notice one LITTLE THING.

Here is the picture from that post noticed in Android Weekly:

http://www.bignerdranch.com/blog/an-investigation-into-flow-and-mortar/

Unfortunately, a lot of developers really see Model layer like this.

Model is not JSON or XML or SQL (which is query language btw).

JSON, XML, etc is just data format, not Model. It is one of the representations of your entities.

Model is a layer, class, object, that manipulates these entities.

Q: What can we see in many apps?
A: Spaghetti code, when all “business logic” is placed into Activities and/or Fragments or now in Flow & Mortar’s Presenters with 300+ lines of code.

With a popular solutions like RxJava it will be reactive spaghetti code! (Actually, it’s better than callbackHelled spaghetti code).

What I want to say? Please, create Models.

Step by step guide:

For example: you need to get list of users from your API.

When you’ll see A/F/P — it’s Activity/Fragment/Presenter.

  1. Create some user entity representation, class or interface (in Java) — User
  2. Write (or use autogenerated) parser from required data format, such as JSON or XML, etc
  3. Write a call to API in your A/F/P (Activity/Fragment/Presenter)
  4. Now delete call to API from your A/F/P
  5. Think about problem in step 3

If you usually write things like API calls, direct Database / ContentProvider / SharedPreferences access in your A/F/P, please stop doing it.

There are many reasons why writing such code in A/F/P is bad practice:

  1. It’s hard to test, because you have to instantiate A/F/P instance and emulate it’s state to just execute some piece of useful code. Of course nobody (98%) of Android Developers writes tests…
  2. Sooner or later you’ll break one of the most important rules: “Don’t repeat yourself”, because later you will need to do same thing in another place of application. I guarantee this.
  3. When you will need to switch to another REST framework (Retrofit?), HTTP client (OkHttp?), Database (Realm?), Parser (Gson?) or another popular thing you’ll have to change a lot of A/F/P classes and then test them, test them again and again (now you’ll think about unit testing).
  4. Reading and, especially, changing classes with more than 300 lines of code is hard and consumes a lot of time which can be spent on more useful things like life. Nobody likes spaghetti code, but a lot of us write it.

Unfortunately, even guys from Google write apps in such bad manner, just see code samples on d.android.com or apps from AOSP or Google I/O app sources.

Model layer is solution

Better variant of getting list of users from API:

  1. Create some user entity representation, class or interface (in Java) — User
  2. Write (or use autogenerated) parser from required data format, such as JSON or XML, etc
  3. Create Model class, for example UserModel
  4. Create a method in UserModel, like “getUsers()” that performs API call and parsing and returns a result, I suggest Observable from RxJava because it’s very flexible and nice, but you can use callbacks, or other mechanisms you want.
  5. Now just create an instance of UserModel in your A/F/P and ask it for a list of users!
  6. Have a nice day ☺

Why it’s better than doing same thing in A/F/P?

  1. You can easily add/change behavior: add caching layer (for example via Database), make additional data transformation (when API changed, etc) or any other additional behavior in one place
  2. You can easily use same Model from many places in the application without repeating yourself
  3. Your A/F/P will be very small, just about 150–200 lines of code on the average
  4. You can create unit tests for Model
  5. You can use Dependency Injection for injecting Models into your A/F/Ps and make architecture even better and cleaner
  6. Clean code

That’s all, hope your life will become better.

P.S. this post can be applied to any kind of development, such as client-side: iOS, Windows Phone or Backend and others. But I wanted to talk about Android Development, because it’s a real problem in our world.

You can follow me in Twitter: @artem_zin

Btw, you can take a look at StorIO — Modern API for SQLiteDatabase and ContentProvider with RxJava support and convenient builders

https://github.com/pushtorefresh/storio

We are working on release 1.0.0 and we will be glad to hear some feedback before release.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.