2016年2月26日 星期五

Android Clean Architecture Digest

I spent a couple of days lately to understand the Clean Architecture from Uncle Bob. The concept has already well explained so here's only my digest.

In a short word : Decouple.

In a few short sentences : Divide your code to layers. The inner ones shouldn't know the implementation of outers. And they communicate through interface and simple data.

There's a great sample : https://github.com/android10/Android-CleanArchitecture. It has 3600+ stars.
Below is one of the great diagrams comes from the blog:




Layers 

  1. UI : It's job is to receive user input and response with data output. Contains activities, fragments, custom view , recycler view adapters, all the Android stuff.
  2. Presenter : It's job is to decides which Use Case to be used. Contains  presenters (as in MVP or MVVM) , view model ( as in MVVM) , 
  3. Use Cases : It's job is to accept and provide tailored data from/to Entities. It also contains some data that only belongs to your application. So it's also called "application" data)
  4. Entities : It's job is to deal with raw data. Like the data from API calls or other day pre-exist before your app started(also called business data). 



Code review

Let me try to relate the diagram with the code from github.  The documentation of each class is in the source code. I just add some notes of my finding here. Note : You need basic knowledge about MVP , rxAndroid , Repository Pattern, and libraries including retrofit, and dagger2 to understand the source code.

There are three modules in this project. Why it uses modules not packages? I guess it's because 1. build time is faster (only the changed code is compile, and you can setup parallel build in gradle 2. It's just more decoupled). 

  1. packages in data  module: This module belongs to the entity layer. 
    1. cache : UseCache is the interface between DataStore(CloudUserDataStore/DiskUserDataStore) and the real implementation UseCacheImp(provided by Dagger)
    2. mapper. This mapper stuff is all around. It just transfer data in entity layers to data that domain layers understand. UserEntityJsonMapper transfer the data from API calls(Json String) to UserEntity.And UserEntityDataMapper to User(used by domain layers)
    3. exception : customized classes extends Java Exception class
    4. executor : JobExecutor provides the Executor for UseCase class (Observable.subscribeOn())
    5. net : RestApi is the XXXService in retrofit , ApiConnection use OkHttpClient to get data.
    6. repository : UserDataRepository (repository pattern) is the main interface between entity layer and domain layer. It contains a UserDataStoreFactory and decides when to use cloud data or disk data. CloudUserDataStore and DiskUserDataStore both  reference the single UserCache instance (cloud for put, disk for get and put). CloudUserDataStore usea  RestApi to retrieve cloud data)
  2. packages in domain module
    1. exception : customized Exception wrapper
    2. executor : PostExecutionThread is the interface letting dagger to inject UIThread to UseCase classes. It has a getScheduler() method that return AndroidSchedulers.mainThread() to GetUserList and GetUserDetails use case classes.
    3. interactor : UseCase abstract class's abstract method buildUseCaseObservable() let its child to implements the logic of getting entity data to domain data(via repository pattern).Its' execute() method bind the observable and subscriber and setup the subscribeOn()/observeOn()DefaultSubscriber  extends rx.Subscriber , provides the call back to presenters 
    4. repository : UserRepository is the contract between UseCase class like GetUserList and UserDataRepository in entity layer.
    5. The User class is a DTO and is domain layer data. (application data)
  3. packages in presentation module
    1. exception : ErrorMessageFactory map Exception class with String
    2. internal.di : This is where dagger 2 is setup.
    3. mapper : UserModelDataMapper  maps domain layer data to view model(data that used to display on UI)
    4. model : UserModel is used in Fragments and Activities
    5. navigation : Navigator is a IntentFactory
    6. presenter : Presenter is the contract between real presenter implementation and view
    7. view : Android UI components and widgets live here.

Testing

Do read this article's testing  section. It said it all.

Thanks for reading. Feel free to advise or correct me.











沒有留言:

張貼留言