Let the wise kids do the Job!
Writing a clean architecture in Android has always been a problem in big teams especially in a rapidly growing project, the team will realized that solving a problem or implementing a feature at some point of time is not enough. The app goes through multiple change cycles and features addition/removal. Incorporating these over a period of time creates havoc in your application if not designed or implemented properly, its a matter of time it will no longer be extendable for features. This is the reason of the need of a well formed and strictly implemented architectural designs.
Provide a Software architecture that will fit any system for Android
Lay ground rules on how to implement strictly the design patterns
Implement a clean project structure, that allow you to build clean, independent and scalable code.
Provides a level of abstraction between UI elements and data operations.
Implement and simplify the logic around data fetching for offline and online users, helping us be an offline-first application. This will enable us to Implement a unidirectional data flow.
To not blocked by new data loads and To fixed the issue on data utilisation.
To have Classes to be designed in such a way that it could be inherited and maximise the code reuse.
The following Design patterns and tools/libraries will be used in our Software Design to achieve all the goals.
Model View Presenter - MVC with Passive view is the root architecture that will be used. Activities and Fragments are considered as Views. Presenters load data from Models and present to the View. Views are made passive and most of the logic is implemented in Presenters. Each Activity may implement a View(interface). Since Activity is the entry point in android, Presenters have to be injected or initialized in Activity class.
Interactor - Each Presenter gets its own instance of an Interactor in place of a singleton DataManager. The interactor is responsible for the same responsibilities as the DataManager but it is only concerned with those data access and processing calls that are required by the feature that it is serving.
Repository Pattern - is to separate the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model. The business logic should be agnostic to the type of data that comprises the data source layer.
It restricts us to work directly with the data in the application and creates new layers for database operations, business logic, and the application’s UI. If an application does not follow the Repository Pattern, it may have the following problems:
Observer Pattern - Establishes a one-to-many dependency between objects. Anytime the state of one of the objects (the "subject" or "observable") changes, all of the other objects ("observers") that depend on it are notified.The subject knows little about its observers. The only thing it knows is that the observers implement or agree to a certain contract or interface.
Adapter Pattern - converts the interface of a class into another interface the clients expects. This pattern mainly adapts one object to another one. Which allows classes to work together despite of incompatible interfaces.
Though Adapter in android was control data and view of ListView(RecyclerView) and it has two role, Data and View. It conflict to Clean-Architecture. The solution is to apply the MVP pattern in separating the logic in the View with Presenter. [More to be clarified].
Tools and Libraries
Dagger 2 - is dependency injection framework. It is based on the Java Specification Request (JSR) 330. It uses code generation and is based on annotations. The generated code is very relatively easy to read and debug. typically used to describe the set of objects which can be injected. classes annotated with @Module are responsible for providing objects which can be injected. Such classes can define methods annotated with @Provides. The returned objects from these methods are available for dependency injection.
RxJava/RxAndroid - is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences. It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.
Retrofit 2 - It makes it relatively easy to retrieve and upload JSON (or other structured data) via a REST based web services. In Retrofit you configure which converter is used for the data serialization. Typically for JSON you use GSon, but you can add custom converters to process XML or other protocols. Retrofit uses the OkHttp library for HTTP requests.
Leakcanery - A memory leak detection library for Android and Java. Enable us to discover and fixed leaks in our app. Applied only on debug build.
“A small leak will sink a great ship.” - Benjamin Franklin
Room - persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. The library helps you create a cache of your app's data on a device that's running your app. This cache, which serves as your app's single source of truth, allows users to view a consistent copy of key information within your app, regardless of whether users have an internet connection.
Butterknife -is small, simple and lightweight, and it makes life as a developer easier. It allows developers to perform injection on arbitrary objects, views and OnClickListeners so they can focus on writing useful code. Consider Android Butter Knife a reduction library. Butter Knife enables focus on logic instead of glue code and reduces development time by reducing redundant coding.
UI Test - Espresso, Robotium, UI Automator. Integration Tests - Robolectric, Unit Tests - JUnit, Mockito, PowerMock