Skip to content

Infrastructure

As you know, this codebase use clean architecture so you have to group your code based on its' purposes and functionality. Here is example of that using our codebase:

📦Root Package
 ┣ 📂data
 ┃ ┣ 📂reqres
 ┃ ┃ ┣ 📂db
 ┃ ┃ ┃ ┗ 📜UserDao.kt
 ┃ ┃ ┃
 ┃ ┃ ┣ 📂model
 ┃ ┃ ┃ ┣ 📜UserEntity.kt
 ┃ ┃ ┃ ┗ 📜UserItem.kt
 ┃ ┃ ┃
 ┃ ┃ ┣ 📂web
 ┃ ┃ ┃ ┣ 📜UserApi.kt
 ┃ ┃ ┃ ┗ 📜UserApiClient.kt
 ┃ ┃ ┃
 ┃ ┃ ┣ 📜UserDataStore.kt
 ┃ ┃ ┗ 📜UserRepository.kt
 ┃ ┃
 ┃ ┗ 📜SampleDatabase.kt
 ┃
 ┣ 📂di
 ┃ ┣ 📂features
 ┃ ┃ ┗ 📜ReqresModule.kt
 ┃ ┃
 ┃ ┣ 📜dbModule.kt
 ┃ ┗ 📜LibModule.kt
 ┃
 ┣ 📂domain
 ┃ ┗ 📂reqres
 ┃ ┃ ┣ 📂model
 ┃ ┃ ┃ ┗ 📜User.kt
 ┃ ┃ ┃
 ┃ ┃ ┣ 📜ReqresInteractor.kt
 ┃ ┃ ┗ 📜ReqresUseCase.kt
 ┃ ┃
 ┣ 📂presentation
 ┃ ┣ 📂form
 ┃ ┃ ┗ 📜FormActivity.kt
 ┃ ┃ 
 ┃ ┗ 📂main
 ┃ ┃ ┣ 📂all
 ┃ ┃ ┃ ┗ 📜AllUserFragment.kt
 ┃ ┃ 
 ┃ ┃ ┣ 📂favorite
 ┃ ┃ ┃ ┗ 📜FavoriteUserFragment.kt
 ┃ ┃ ┃
 ┃ ┃ ┣ 📜MainActivity.kt
 ┃ ┃ ┣ 📜MainViewModel.kt
 ┃ ┃ ┗ 📜UserAdapter.kt
 ┃ ┃
 ┣ 📂utils
 ┃ ┗ 📜Variables.kt
 ┃
 ┗ 📜SampleApplication.kt

Let's dive in on each and every one of them:

Data (Layer)¶

This layer basically handle all data source, from getting data from web service or saving it to local database. Inside it, you can save as many service as you need and you can name that service as you want but always represent what it do. Take a look at the example above, inside it we have reqres service. And from there, let's break what inside of every service should look like.

  • db, this package is where you store your Database Access Object. Keep in mind that we use Room Database for Local Database Framework. And it should always inherit DevDao

    Naming convention for dao is: {Purpose}Dao.kt

  • model, this package is where you store your model object either is for web service or local database.

    Naming convention for object from API is : {Purpose}Item.kt
    Naming convention for object for Local Database is : {Purpose}Entity.kt

  • web, this package contains class for hitting API purposes. And do remember that we use Retrofit for that.

  • ApiClient, is an interface where we define our endpoint > Naming convention for ApiClient is : {Purpose}ApiClient.kt
  • Api, is a class that implement ApiClient, should always implement WebService > Naming convention for Api is : {Purpose}Api.kt

Next to the three packages we just mentioned, you have two other classes that you should define. Both of them are:

  • Repository, it's an interface that define every process that you do with data source. Like syncing data, hitting api, load data from api, etc. And all of that process define in method each.

    Naming convention for Repository is : {Purpose}Repository.kt

  • DataStore, it's a class that inherit Repository. In this class you after you override the method in Repository, you define how you want to do that in every one of them.

    Naming convention for DataStore is : {Purpose}DataStore.kt

P.S. outside all of service package, now you have Database class for Room Database. It's should have next to all of service package if you implement Local Database.

Naming convention for database is: {AppName}Database.kt

DI (Dependency Injection)¶

As you know, this codebase use Koin to implement Dependency injection. To store modules, you store it inside this package. But do remember, for injection that used globally you store it right inside di package but if the injection for specific-purposes like ViewModel you store it inside features package by creating a Kotlin file.

Naming convention for that file is : {Purpose}Module.kt

Domain (Layer)¶

This package is where you map your model object from data layer to a new model object to use in presentation layer. Beside doing that, you should also consider removing variables that you do not use so it's only what matters showed. The package inside domain package should always follow the data layer. And inside of every packages, you should have:

  • Model Package, here you define new model object that you will use in presentation layer

    Naming convention for model object in domain layer is : {Purpose}.kt

  • UseCase, it's an interface where you define every process that you use to bridge the data layer and the presentation layer to methods.

    Naming convention for UseCase is : {Purpose}UseCase.kt

  • Interactor, here you implement usecase and do the data mapping that we talked about

    Naming convention for Interactor is : {Purpose}Interactor.kt

Presentation (Layer)¶

As written in the package, this package handle all the presentation or everything that you on see on the device. it stores your activities, fragments, adapters, and even ViewModels. You can create package inside it based on page you need.

Utils¶

This package is where you put all of your utilities and project-specific configuration like customView or other utility that you use across your apps. You can group utilities into packages inside utils package based on its function.