Skyscanner Android Architecture

v1.0 RC1

Layered Structure

  • Entity
  • Domain
  • Data
  • Presentation
  • Dependency Injection

Layered Structure

  • Structuring your code
  • Telling you the direction of dependencies
  • Creating decoupled designs
  • Keeping 3rd party tools separated

The Layers help you in:

Entity Layer

  • Any class that solves a concrete, well separated business problem
  • Pure Java, no 3rd party tools are present in this layer
  • Entity objects /= dumb DTO objects

Examples:

  • Handling Recent Searches
  • Getting the Inspiration Feed contents
  • Managing Pricing Service polls
  • Every model class that the *Repositories operate on

Domain Layer

  • Non-trivial, potentially reusable use cases live here
  • Pure Java, no 3rd party tools are present in this layer
  • Use cases ~= tasks that act on multiple Entity objects and process them in some way

Examples:

  • Assembling the Inspiration Feed contents

Presentation Layer

  • Everything related to presentation / display
  • Android components & resources live here
  • 3rd party tools live here
  • Not a pure Java layer

Examples:

  • Fragments & Activities
  • Adapters & Cells
  • Custom Views
  • Currently even Presenters

Data Layer

  • Everything related to data storage and networking live here
  • Android components live here
  • 3rd party tools live here
  • Not a pure Java layer

Examples:

  • Shared Preferences
  • OkHttp & co
  • SQLite
  • Jackson & other data serialization tools

DI Layer

  • Everything related to Dependency Injection tools
  • The DI tools should not pollute the codebase too much, so we separate it
  • E.g. Domain classes should not worry about DI

Examples:

  • Dagger Modules
  • Dagger Components
  • Custom Dagger Scope Annotations

Models

Data Layer Models

  • Mostly Data Transfer Objects
  • Normalized schema
  • Optimized for network payload size
  • Concerned about data (de-)serialization
    • JSON, ProtoBuf, etc.

Examples:

  • FeedItemQuoteV2DTO

Entity Layer Models

  • Denormalized schema
  • Has all the low level details
  • Optimized for processing them in Entity / Domain objects

Examples:

  • FeedItemQuoteV2
    • Price Age Seconds: Int
    • Quote Price Currency ID: String
    • Quote Price Amount: Double

Crossing Boundaries

  • Mapper objects should be used to convert models between layers

Examples:

  • Data -> Entity mapping: FeedModelMapper
  • Entity -> Presentation mapping: FeedItemMapper

Reactive MVP

Reactive MVP

MVP is working ok, but:

We tend to have fat Presenters

...and...

We don't have a common pattern for control-flow

Fat Presenters

  • Fat = too complex, too many responsibilities
  • The Layered approach is helping
    • Complexity is extracted into Domain, Entity and Data Layer objects
    • A block of complex BL => A use case
    • Mapping stuff => A mapper

Control Flow Pattern

  • Embrace Rx in MVP, where it makes sense
  • Enter the Reactive MVP with Passive View
  • The View exposes streams for:
    • User interaction
    • Navigation results (Autosuggest / Calendar selections)
  • The Presenter composes the streams and invokes a single display method on the View

Some questions remain

  • Better pattern for Navigation from Presenters
  • Defining Rx threading policy for Use Cases

 

But: The major building blocks & patterns are defined

Going forward

  1. Sitting down with all the squads - December
    • Discuss questions & concerns
    • Check potential problematic scenarios
  2. Finishing up the V1 doc, considering the feedbacks - December
  3. Agree on the rollout plan - 2017 Jan and forward
    • New code should use the new arch
    • Refactor existing components strategically

Q & A

Android Architecture

By rzsombor

Android Architecture

  • 617