Slide 1

Slide 1 text

Architecture for AppBundles DevFest Ukraine

Slide 2

Slide 2 text

Architecture for Dynamic Feature Modules DevFest Ukraine

Slide 3

Slide 3 text

What dynamic feature modules mean for my existing architecture? DevFest Ukraine

Slide 4

Slide 4 text

Will my team need to spend 2 man-years refactoring the code just to make our app compatible with that new thing Google announced at the I/O? DevFest Ukraine

Slide 5

Slide 5 text

Architecture for AppBundles DevFest Ukraine

Slide 6

Slide 6 text

Mateusz Herych Android Team Lead, IG Co-organizer, GDG Kraków Ex-organizer, Droidcon Kraków GDE

Slide 7

Slide 7 text

Trading 101

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Our developer life up to January 2018

Slide 12

Slide 12 text

Our developer life up to January 2018 - app module for the Android stuff

Slide 13

Slide 13 text

Our developer life up to January 2018 - app module for the Android stuff - core module for the business logic

Slide 14

Slide 14 text

Our developer life up to January 2018 - app module for the Android stuff - core module for the business logic - data module for Jackson POJOs, Retrofit gateways, etc. - App depends on core & data. Data depends on core.

Slide 15

Slide 15 text

Problems?

Slide 16

Slide 16 text

Our developer life up to January 2018 - Lots of useless interfaces just to map stuff from one module to another.

Slide 17

Slide 17 text

Our developer life up to January 2018 - Lots of useless interfaces just to map stuff from one module to another. (aka well abstracted, clean code)

Slide 18

Slide 18 text

Our developer life up to January 2018 - Lots of useless interfaces just to map stuff from one module to another. (aka well abstracted, clean code) - Mappers everywhere

Slide 19

Slide 19 text

Our developer life up to January 2018 - Lots of useless interfaces just to map stuff from one module to another. (aka well abstracted, clean code) - Mappers everywhere - Even simplest changes required recompiling all of the modules - quite a massive incremental build times.

Slide 20

Slide 20 text

Our developer life up to January 2018 - Lots of useless interfaces just to map stuff from one module to another. (aka well abstracted, clean code) - Mappers everywhere - Even simplest changes required recompiling all of the modules - quite a massive incremental build times. - Single feature spread across entire codebase.

Slide 21

Slide 21 text

New challenge

Slide 22

Slide 22 text

New challenge - Expanding to a new market

Slide 23

Slide 23 text

New challenge - Expanding to a new market - Produce a new trading app for that market

Slide 24

Slide 24 text

New challenge - Expanding to a new market - Produce a new trading app for that market - It has a relatively small functionality subset of the ‘monolith’

Slide 25

Slide 25 text

New challenge - Expanding to a new market - Produce a new trading app for that market - It has a relatively small functionality subset of the ‘monolith’ - Most of those features behave the same

Slide 26

Slide 26 text

New challenge - Expanding to a new market - Produce a new trading app for that market - It has a relatively small functionality subset of the ‘monolith’ - Most of those features behave the same - … and look the same

Slide 27

Slide 27 text

New challenge - Expanding to a new market - Produce a new trading app for that market - It has a relatively small functionality subset of the ‘monolith’ - Most of those features behave the same - … and look the same - Core logic - dealing… is completely different.

Slide 28

Slide 28 text

New challenge - Expanding to a new market - Produce a new trading app for that market - It has a relatively small functionality subset of the ‘monolith’ - Most of those features behave the same - … and look the same - Core logic - dealing… is completely different. - All the logic we do for the new app - we want it to be reusable in the monolith later on.

Slide 29

Slide 29 text

Structure

Slide 30

Slide 30 text

Onboarding Session Markets Payments Dealing

Slide 31

Slide 31 text

Onboarding Session Markets Payments Dealing Base App

Slide 32

Slide 32 text

Payments Onboarding Session Markets Payments Dealing Base App TINY! Only utilities here TINY! Just gluing stuff together.

Slide 33

Slide 33 text

Few decisions - Feature modules don’t depend on each other - UI and the business logic are split - App depends on all the feature modules - All feature modules depend on base - (which means ‘base’ has to be app-agnostic)

Slide 34

Slide 34 text

Let’s see some code.

Slide 35

Slide 35 text

Navigation

Slide 36

Slide 36 text

Because modules need to navigate between each other.

Slide 37

Slide 37 text

Imagine - User see a market list (that belongs to the `markets` module)

Slide 38

Slide 38 text

Imagine - User see a market list (that belongs to the `markets` module) - Tapping on the market item moves you to a dealing screen

Slide 39

Slide 39 text

Imagine - User see a market list (that belongs to the `markets` module) - Tapping on the market item moves you to a dealing screen - (which belongs to the `dealing` module, which isn’t known by the `markets` module)

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

markets

Slide 42

Slide 42 text

app

Slide 43

Slide 43 text

app, again

Slide 44

Slide 44 text

Navigation - Within the module, you just inject your navigator interface… voila!

Slide 45

Slide 45 text

Navigation - Within the module, you just inject your navigator interface… voila! - Each module defines the interface with all the cross-module navigation actions it may trigger.

Slide 46

Slide 46 text

Navigation - Within the module, you just inject your navigator interface… voila! - Each module defines the interface with all the cross-module navigation actions it may trigger. - Then, the exact behavior, is defined by the `app` module (which defines the navigation between modules)

Slide 47

Slide 47 text

Decorators.

Slide 48

Slide 48 text

Sometimes you display things from different modules, on a single Activity.

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

markets markets onboarding dealing accounts

Slide 51

Slide 51 text

NavigationDrawer

Slide 52

Slide 52 text

NavigationDrawer Base

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Base

Slide 55

Slide 55 text

Decorators - Actual DecoratorCommand implementations can be defined within modules

Slide 56

Slide 56 text

Decorators - Actual DecoratorCommand implementations can be defined within modules - App decides which DecoratorCommands to use

Slide 57

Slide 57 text

Decorators - Actual DecoratorCommand implementations can be defined within modules - App decides which DecoratorCommands to use - Some Decorators make use from the contract - e.g. you need to have R.id.bottomContainer within your Activity’s layout

Slide 58

Slide 58 text

Guess what, we were pretty happy about this.

Slide 59

Slide 59 text

And then… AppBundles!

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

First impression: nice, we’ll be able to benefit from our shiny & fresh modular structure!

Slide 62

Slide 62 text

Second impression: …. Ooops!

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

Some blogposts claim, that Dynamic Feature Modules are like Android Library Modules. But there’s a pretty fundamental difference.

Slide 65

Slide 65 text

Dynamic Feature modules depend on your ‘base app’. Not vice versa.

Slide 66

Slide 66 text

In other words: ‘app’ (or ‘base’) won’t be able to access the classes of a dynamic feature module.

Slide 67

Slide 67 text

Instead, dynamic feature module, will have an access to the classes of the `base` module.

Slide 68

Slide 68 text

But this actually makes a lot of sense.

Slide 69

Slide 69 text

You don’t have to change your architecture to support AppBundles - you can benefit from them without much of the effort.

Slide 70

Slide 70 text

Purpose of our modular approach: good separation, lack of coupling between features enforced in compile-time.

Slide 71

Slide 71 text

Purpose of Dynamic Feature Modules: smaller APK size (good separation coming more as a ‘side-effect’).

Slide 72

Slide 72 text

Onboarding Session Markets Payments Dealing Base App

Slide 73

Slide 73 text

Onboarding Session Markets Payments Dealing Base App Dynamic Feature Module A Dynamic Feature Module B

Slide 74

Slide 74 text

Common Issues - Starting Activities

Slide 75

Slide 75 text

Common Issues - Starting Activities - Attaching Fragments / other UI components to ‘base’ activities

Slide 76

Slide 76 text

Starting Activities Not much to talk about really. Simple as:

Slide 77

Slide 77 text

What about non Activities? TODO TODO TODO

Slide 78

Slide 78 text

What is a good candidate for a dynamic feature module? - Something that only portion of your users need. - Something that users won’t likely need in a short-time after the installation.

Slide 79

Slide 79 text

What is a good candidate for a dynamic feature module? - Something that only portion of your users need. - Something that users won’t likely need in a short-time after the installation. Document Upload feature? Maybe Payments?

Slide 80

Slide 80 text

Start using AppBundles.

Slide 81

Slide 81 text

You can benefit from them at nearly zero effort.

Slide 82

Slide 82 text

Dynamic Feature Modules - you may need them, but you may not.

Slide 83

Slide 83 text

Also… they aren’t that scary and don’t really require you to rewrite everything at once.

Slide 84

Slide 84 text

Thanks! QA time