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
- Sitting down with all the squads - December
- Discuss questions & concerns
- Check potential problematic scenarios
- Finishing up the V1 doc, considering the feedbacks - December
- 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