Skip to content

Latest commit

 

History

History
119 lines (81 loc) · 5.68 KB

ArchitectureLearningJourney.md

File metadata and controls

119 lines (81 loc) · 5.68 KB

Architecture Journey

In this journey, you will look at the Lnj Merchants app architecture: its layers, key classes, and the interactions between them.

Goals and requirements

The goals for the app architecture are:

  • Follow the official architecture guidance as closely as possible.
  • Easy for developers to understand, nothing too experimental.
  • Support multiple developers working on the same codebase.
  • Minimize build times.

Architecture Overview

The app architecture has three layers: a data layer, a domain layer, and a UI layer.

Diagram showing overall app architecture

The architecture follows a reactive programming model. With the data layer at the bottom, the key concepts are:

  • Higher layers react to changes in lower layers.
  • Events flow down.
  • Data flows up.

The data flow is achieved using streams, implemented using Kotlin Flows.

Example: Displaying sliders on the Home screen

When the app is first run it will attempt to load a list of images resources from a remote server. Once loaded, these are shown to the user on the home screen.

The following diagram shows the events which occur and how data flows from the relevant objects to achieve this.

whole architecture

Here's what's happening in each step. The easiest way to find the associated code is to load the project into Android Studio and search for the text in the Code column (handy shortcut: tap ⇧ SHIFT twice).

Step Description Code
1 The HomeViewModel calls GetSliderImagesUseCase to obtain a stream of images. While waiting, the slider state is set to Loading. Search for usages of binding.slidersShimmerLayout.visible
2 provideRetrofit calls the REST API on the remote server. remoteDataSource.requestAllProviders
3 provideRetrofit receives the network response from the remote server. remoteDataSource.requestAllProviders
4 When HomeViewModel receives the response slider resources it updates the home state to Success. HomeFragmntthen uses the response resources in the sliders state to render the screen. Search for instances of setupSliders

UI Layer

The UI layer comprises:

The ViewModels receive streams of data from use cases and repositories and transform them into UI state. The UI elements reflect this state, and provide ways for the user to interact with the app. These interactions are passed as events to the ViewModel where they are processed.

architecture-4-ui-layer

Modeling UI state

UI state is modeled as a sealed hierarchy using interfaces and immutable data classes. State objects are only ever emitted through the transformation of data streams. This approach ensures that:

  • The UI state always represents the underlying app data - the app data is the source-of-truth.
  • The UI elements handle all possible states.

Example: sliders on Home screen

The sliders (a list) of String resources on the Home screen are modeled using ViewState. This is a sealed class which creates a hierarchy of two possible states:

  • Loading indicates that the data is loading
  • Success indicates that the data was loaded successfully. The Success state contains the list of news resources.
  • NetworkError indicates that there is a network error
  • Error indicates that there is an error in parsing

The slider is passed to the HomeFragmet, which handles both of these states.

Transforming streams into UI state

ViewModels receive streams of data as cold flows from one or more use cases or repositories. These are combined together, or simply mapped, to produce a single flow of UI state. This single flow is then converted to a hot flow using stateIn. The conversion to a state flow enables UI elements to read the last known state from the flow.

Processing user interactions

User actions are communicated from UI elements to ViewModels using regular method invocations. These methods are passed to the UI elements as lambda expressions.