Skip to content

YosifKalchev/CalorieTracker

Repository files navigation

Calorie Tracker

Multi module app

Architecture

Feature related code is placed inside one of the feature modules. We can think about each feature as the reusable component, equivalent of microservice or private library.

The modularized code-base approach provides few benefits:

  • better separation of concerns. Each module has a clear API., Feature related classes live in different modules and can't be referenced without explicit module dependency.
  • features can be developed in parallel eg. by different teams
  • each feature can be developed in isolation, independently from other features
  • faster compile time

Module types and module dependencies

We have different kinds of modules in the application:

  • app module - this is the main module. It contains code that wires multiple modules together and fundamental application configuration.
  • buildSrc module - this module contains all version values so they can be reused/changed easily throught all the .build files
  • core UI module - contains all shared data related to UI (this allows us to not import compose dependencies in data and domain modules)
  • core module - contains all shared data apart from UI related
  • feature modules - the most common type of module containing all code related to a given feature (containing data , domain and presentation submodules)

Feature module structure

Clean architecture is the "core architecture" of the application, so each feature module contains own set of Clean architecture layers:

Each feature module contains non-layer components and 3 layers with distinct set of responsibilities.

Presentation layer

This layer is closest to what the user sees on the screen. The presentation layer is designed with MVVM - Jetpack ViewModel used to preserve data across activity restart, actions modify the common state of the view and then new state is edited to a view via Kotlin Flows to be rendered).

Components:

  • View (Fragment) - presents data on the screen and pass user interactions to View Model. Views are hard to test, so they should be as simple as possible.
  • ViewModel - dispatches (through Kotlin Flows) state changes to the view and deals with user interactions.
  • ViewState - common state for a single view

Domain layer

This is the core layer of the application. Notice that the domain layer is independent of any other layers. This allows to make domain models and business logic independent from other layers. In other words, changes in other layers will have no effect on domain layer eg. changing database (data layer) or screen UI (presentation layer) ideally will not result in any code change withing domain layer.

Components:

  • UseCase - contains business logic
  • DomainModel - defines the core structure of the data that will be used within the application. This is the source of truth for application data.
  • Repository interface - required to keep the domain layer independent from the data layer (Dependency inversion).

Data layer

Manages application data and exposes these data sources as repositories to the domain layer. Typical responsibilities of this layer would be to retrieve data from the internet and optionally cache this data locally.

Components:

  • Repository is exposing data to the domain layer. Depending on application structure and quality of the external APIs repository can also merge, filter, and transform the data. The intention of these operations is to create high-quality data source for the domain layer, not to perform any business logic (domain layer use case responsibility).

  • Mapper - maps data model to domain model (to keep domain layer independent from the data layer).

  • RetrofitService - defines a set of API endpoints.

  • DataModel - defines the structure of the data retrieved from the network and contains annotations, so Retrofit (Moshi) understands how to parse this network data (XML, JSON, Binary...) this data into objects.

Dependency management

This project utilizes multiple mechanics to easily share the same versions of dependencies such as base-module to be interited from and BuildSrc module containing all version values to be reused.

Design decisions

Read related articles to have a better understanding of underlying design decisions and various trade-offs.

Android Studio

  1. Android Studio -> File -> New -> From Version control -> Git
  2. Enter https://github.com/YosifKalchev/CalorieTracker.git into URL field an press Clone button

Command-line + Android Studio

  1. Run git clone https://github.com/YosifKalchev/CalorieTracker.git command to clone project
  2. Open Android Studio and select File | Open... from the menu. Select cloned directory and press Open button

Cheat sheet

Android projects

  • to be updated...

Author

Follow me

About

Multi module app

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages