This is a simple architecture for Android project made in Scala using Cats and ScalaZ libraries
-
android: This module contains the Android SDK with Activities, Fragments and so on, used in your project. Every screen have jobs, with the actions in your UI and Ui Actions (We speak about them later)
-
services: This module contains services for connecting to out of the applications. For example: API, Repository, Disk, so on
-
commons: This module contains types and resources used in other module in order to compose the result of the methods
Our Activities, Fragment and other screen of Android call to action using Jobs. Jobs are a group of methods that contain the things that the UI can do. For example: loadItems, showItem, markAsDone, etc
The principles of the Jobs is that they can connect to the UI (using Ui Actions) and api, repository or whatever (using Services)
In order to can compose the methods of the Ui and Services, all methods must return the same type. The type is define in commons module and it's the next:
type TaskService[A] = XorT[Task, ServiceException, A]
Our TaskService type is a Task of ScalaZ in other to can do async tasks and using a Xor of Cats for exceptions and value of the method
For example, a method of our Job can have calls to Ui and Services:
def loadAnimals: TaskService[Unit] = {
for {
_ <- uiActions.showLoading()
animals <- apiService.getAnimals()
_ <- uiActions.showContent()
_ <- uiActions.loadAnimals(animals)
} yield ()
}
In the activity we can do that:
val tasks = (jobs.initialize |@| jobs.loadAnimals).tupled
tasks.resolveServiceOr(_ => jobs.showError)
We can compose initialize and loadAnimals in a Applicative and using TaskOps (defined in commons module) we can launch the async task and launch the error if the task doesn't work