Refactoring Wunderlist. UA Mobile 2016.

143
Refactoring Wunderlist for Android César Valiente - Episode I. The presentation layer -

Transcript of Refactoring Wunderlist. UA Mobile 2016.

Page 1: Refactoring Wunderlist. UA Mobile 2016.

Refactoring Wunderlist for Android

César Valiente

- Episode I. The presentation layer -

Page 2: Refactoring Wunderlist. UA Mobile 2016.

Who is this guy?

Image Placeholder

César Valiente Android Engineer @Wunderlist (@Microsoft)

Android Google Developer Expert (GDE)

+CesarValiente @CesarValiente

Page 3: Refactoring Wunderlist. UA Mobile 2016.

This is a story of…

Page 4: Refactoring Wunderlist. UA Mobile 2016.

evolution

Page 5: Refactoring Wunderlist. UA Mobile 2016.

growth

evolution

Page 6: Refactoring Wunderlist. UA Mobile 2016.

growth

simplicity

evolution

Page 7: Refactoring Wunderlist. UA Mobile 2016.

growth

simplicity

evolution

improvement

Page 8: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Page 9: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Android Layer

Presentation layer (UI and Android stuff)

Android project

Page 10: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Android Layer

Presentation layer (UI and Android stuff)

Android project

Sync Layer

Model layer (Business logic)

Java project

Page 11: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Android Layer

Presentation layer (UI and Android stuff)

Android project

Sync Layer

Model layer (Business logic)

Java project

Network Layer

Network layer (Accessing to the API data)

Java project

Page 12: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Android Layer

Presentation layer (UI and Android stuff)

Android project

Sync Layer

Model layer (Business logic)

Java project

Network Layer

Network layer (Accessing to the API data)

Java project

Sync boundaries

Page 13: Refactoring Wunderlist. UA Mobile 2016.

How is Wunderlist built?

Android Layer

Presentation layer (UI and Android stuff)

Android project

Sync Layer

Model layer (Business logic)

Java project

Network Layer

Network layer (Accessing to the API data)

Java project

Sync boundaries Network boundaries

Page 14: Refactoring Wunderlist. UA Mobile 2016.

Dependency rule

Page 15: Refactoring Wunderlist. UA Mobile 2016.

Network

Dependency rule

Page 16: Refactoring Wunderlist. UA Mobile 2016.

Sync

Network

Dependency rule

Page 17: Refactoring Wunderlist. UA Mobile 2016.

Presentation

Sync

Network

Dependency rule

Page 18: Refactoring Wunderlist. UA Mobile 2016.

Presentation

Sync

Network

Dependency rule

The outer model knows the inner, not viceversa.

Page 19: Refactoring Wunderlist. UA Mobile 2016.

Problems?

Page 20: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Page 21: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Page 22: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Database in presentation layer (since it was our only Android related layer).

Page 23: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Difficult to test: framework dependencies.

Database in presentation layer (since it was our only Android related layer).

Page 24: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Difficult to test: framework dependencies.

Database in presentation layer (since it was our only Android related layer).

Cache in the sync layer.

Page 25: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Difficult to test: framework dependencies.

Database in presentation layer (since it was our only Android related layer).

Cache in the sync layer.

Complex data schemes used also in the presentation layer, not needed here.

Page 26: Refactoring Wunderlist. UA Mobile 2016.

Problems?Activities/Fragments become GOD classes.

Responsibilities are messed up.

Difficult to test: framework dependencies.

Database in presentation layer (since it was our only Android related layer).

Cache in the sync layer.

Complex data schemes used also in the presentation layer, not needed here.

We wanted to do it better!

Page 27: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?

Page 28: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

Page 29: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

We are going to decouple the different core elements of our app.

Page 30: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

We are going to decouple the different core elements of our app.

We are going to improve the way we fetch data.

Page 31: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

We are going to decouple the different core elements of our app.

We are going to improve the way we fetch data.

We are going to make testing easier to do, and increase our test coverage.

Page 32: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

We are going to decouple the different core elements of our app.

We are going to improve the way we fetch data.

We are going to make testing easier to do, and increase our test coverage.

We are going to improve our codebase.

Page 33: Refactoring Wunderlist. UA Mobile 2016.

What are we going to do?We are going to separate responsibilities. Yes, Even more!

We are going to REFACTOR

We are going to decouple the different core elements of our app.

We are going to improve the way we fetch data.

We are going to make testing easier to do, and increase our test coverage.

We are going to improve our codebase.

Page 34: Refactoring Wunderlist. UA Mobile 2016.

Presentation layer

Page 35: Refactoring Wunderlist. UA Mobile 2016.

Presentation layer

App/UI

(Android project)

Page 36: Refactoring Wunderlist. UA Mobile 2016.

Presentation layer

App/UI

(Android project)

UI domain

(Java project)

Page 37: Refactoring Wunderlist. UA Mobile 2016.

Presentation layer

App/UI

(Android project)

UI domain

(Java project)

DB/Cache

(Android project)

Page 38: Refactoring Wunderlist. UA Mobile 2016.

Everything starts with the Model View Presenter (MVP) 😎

Page 39: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

Everything starts with the Model View Presenter (MVP) 😎

Page 40: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

Everything starts with the Model View Presenter (MVP) 😎

Page 41: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

Everything starts with the Model View Presenter (MVP) 😎

Page 42: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

User interacts with the app

Everything starts with the Model View Presenter (MVP) 😎

Page 43: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

Starts the process

User interacts with the app

Everything starts with the Model View Presenter (MVP) 😎

Page 44: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

Starts the process

Executes use caseUser interacts

with the app

Everything starts with the Model View Presenter (MVP) 😎

Page 45: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

Starts the process

Executes use case

Returns the result

User interacts with the app

Everything starts with the Model View Presenter (MVP) 😎

Page 46: Refactoring Wunderlist. UA Mobile 2016.

VIEW

Activity/Fragment

PRESENTER

Man in the middle

MODEL

Business logic

Starts the process

Executes use case

Updates view Returns the result

User interacts with the app

Everything starts with the Model View Presenter (MVP) 😎

Page 47: Refactoring Wunderlist. UA Mobile 2016.
Page 48: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

Page 49: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

VIEWCALLBACK

USE CASE

Page 50: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

VIEWCALLBACK

USE CASE

implements and passes it to the presenter

Page 51: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

VIEWCALLBACK

USE CASE

implements and passes it to the presenter

creates an instance and passes it to the

presenter

Page 52: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

VIEWCALLBACK

USE CASE

implements and passes it to the presenter

creates an instance and passes it to the

presenter

will execute it to start the process

Page 53: Refactoring Wunderlist. UA Mobile 2016.

VIEW PRESENTER

VIEWCALLBACK

USE CASE

implements and passes it to the presenter

creates an instance and passes it to the

presenter

will invoke it to communicate back (when we have

the result)

will execute it to start the process

Page 54: Refactoring Wunderlist. UA Mobile 2016.

ViewCallback

Page 55: Refactoring Wunderlist. UA Mobile 2016.

public interface ViewCallback { void showProgressDialog(); void hideProgressDialog(); void updateList(List content); }

Page 56: Refactoring Wunderlist. UA Mobile 2016.

View

Page 57: Refactoring Wunderlist. UA Mobile 2016.

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

Page 58: Refactoring Wunderlist. UA Mobile 2016.

private View progressDialog; private Adapter adapter; private SharingPresenter sharingPresenter; public void onCreate (Bundle onSavedInstanceState) { super.onCreate(onSavedInstanceState); bindViews(); setupPresenters(); }

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

Page 59: Refactoring Wunderlist. UA Mobile 2016.

private View progressDialog; private Adapter adapter; private SharingPresenter sharingPresenter; public void onCreate (Bundle onSavedInstanceState) { super.onCreate(onSavedInstanceState); bindViews(); setupPresenters(); }

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

private void setupPresenters () { GetListMembershipUseCase getListMembershipUseCase = new GetListMembershipUseCase( listId, appDataController); sharingPresenter = new SharingPresenter ( this, getListMembershipUseCase); }//——————— next slides ———————//

Page 60: Refactoring Wunderlist. UA Mobile 2016.
Page 61: Refactoring Wunderlist. UA Mobile 2016.

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

//——————————-— previous slide (setup) ———————————-—//

//——————— next slide (presenter invocation) ———————//

Page 62: Refactoring Wunderlist. UA Mobile 2016.

@Override void showProgressDialog() { progressDialog.show(); } @Override void hideProgressDialog() { progressDialog.hide(); } @Override void updateList(List<Memberships> list) { adapter.updateContent(list); } }

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

//——————————-— previous slide (setup) ———————————-—//

//——————— next slide (presenter invocation) ———————//

implements ViewCallback {

Page 63: Refactoring Wunderlist. UA Mobile 2016.
Page 64: Refactoring Wunderlist. UA Mobile 2016.

//——————————— slide 1 (setup) —————————-—//

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

//————— slide 2 (ViewCallback impl) ————-//

Page 65: Refactoring Wunderlist. UA Mobile 2016.

@OnClick private void showListMembers () { sharingPresenter.getListMembers(); }

//——————————— slide 1 (setup) —————————-—//

public class SharingFragmentActivity extends WLFragmentActivity implements ViewCallback {

//————— slide 2 (ViewCallback impl) ————-//

Page 66: Refactoring Wunderlist. UA Mobile 2016.

Presenter

Page 67: Refactoring Wunderlist. UA Mobile 2016.

public class SharingPresenter extends Presenter {

Page 68: Refactoring Wunderlist. UA Mobile 2016.

public class SharingPresenter extends Presenter {

private ViewCallback viewCallback; private GetListMembershipUseCase getListMembershipUseCase; public SharingPresenter ( ViewCallback viewCallback, GetListMembershipUseCase getListMembershipUseCase) { this.viewCallback = viewCallback; this.getListMembershipUseCase = getListMembershipUseCase; }

//——————— next slides ———————//

Page 69: Refactoring Wunderlist. UA Mobile 2016.
Page 70: Refactoring Wunderlist. UA Mobile 2016.

public class SharingPresenter extends Presenter {

//——————————-— previous slide (setup) ———————————-—//

Page 71: Refactoring Wunderlist. UA Mobile 2016.

@Override public void onStart() { EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); }

public class SharingPresenter extends Presenter {

//——————————-— previous slide (setup) ———————————-—//

Page 72: Refactoring Wunderlist. UA Mobile 2016.

@Override public void onStart() { EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); }

public class SharingPresenter extends Presenter {

//——————————-— previous slide (setup) ———————————-—//

public void onEventMainThread(ListMembershipEvent event) { viewCallback.hideProgressDialog(); viewCallback.updateList(event.getContent()); }

//——————— next slide (Use Case execution) ———————//

Page 73: Refactoring Wunderlist. UA Mobile 2016.
Page 74: Refactoring Wunderlist. UA Mobile 2016.

public class SharingPresenter extends Presenter {

//————————————- slide 1 (setup) ———————————————————-—//

//———————————— slide 2 (listening for events) ———————//

Page 75: Refactoring Wunderlist. UA Mobile 2016.

public void showListMembers () { viewCallback.showProgressDialog(); getListMembershipUseCase.execute(); } }

public class SharingPresenter extends Presenter {

//————————————- slide 1 (setup) ———————————————————-—//

//———————————— slide 2 (listening for events) ———————//

Page 76: Refactoring Wunderlist. UA Mobile 2016.
Page 77: Refactoring Wunderlist. UA Mobile 2016.

MODEL

Page 78: Refactoring Wunderlist. UA Mobile 2016.

MODEL

Use Cases

Page 79: Refactoring Wunderlist. UA Mobile 2016.

UI-Items, DB, Cache, etc.

MODEL

Use Cases

Page 80: Refactoring Wunderlist. UA Mobile 2016.

Use case

Page 81: Refactoring Wunderlist. UA Mobile 2016.

public class GetListMembershipUseCase implements UseCase<List<WLMembership>> {

Page 82: Refactoring Wunderlist. UA Mobile 2016.

public class GetListMembershipUseCase implements UseCase<List<WLMembership>> {

private String listId; private AppDataController appDataController; public GetListUseCase( String listId, AppDataController appDataController) { this.listId = listId; this.appDataController = appDataController; }

Page 83: Refactoring Wunderlist. UA Mobile 2016.

public class GetListMembershipUseCase implements UseCase<List<WLMembership>> {

private String listId; private AppDataController appDataController; public GetListUseCase( String listId, AppDataController appDataController) { this.listId = listId; this.appDataController = appDataController; } @Override public void execute() { appDataController.get(ApiObjectType.MEMBERSHIP, listId); } }

Page 84: Refactoring Wunderlist. UA Mobile 2016.

How were we fetching data?

Page 85: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

DB

Presentation layer

1. Using loaders

Page 86: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

DB

Presentation layer

1. Using loaders

Page 87: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

DB

Presentation layer

1. Using loaders

Page 88: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

BUS

Event or data is fired

Presentation layer

2. Using loaders + Bus

Page 89: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

BUS

Subscription

Event or data is fired

Presentation layer

2. Using loaders + Bus

Page 90: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

BUS

Subscription

Event or data is fired

Data

Presentation layer

2. Using loaders + Bus

Page 91: Refactoring Wunderlist. UA Mobile 2016.

LOADER

Activity/Fragment

BUS

Subscription Data

Event or data is fired

Data

Presentation layer

2. Using loaders + Bus

Page 92: Refactoring Wunderlist. UA Mobile 2016.

And how do we fetch data now? (an evolution of approaches)

Page 93: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

Page 94: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

Page 95: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

Page 96: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

3

Page 97: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

3

4

Page 98: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

5

3

4

Page 99: Refactoring Wunderlist. UA Mobile 2016.

1. Use case that returns data. Synchronous.

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

5

6

3

4

Page 100: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

Page 101: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

Page 102: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

Page 103: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

3

Page 104: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

3

4

Page 105: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

5

3

4

Page 106: Refactoring Wunderlist. UA Mobile 2016.

2. Use case using callback. Asynchronous.

2

Presenter

View

Presentation layer Model

UI domaindb/

cache

Use Case

1

2

5

6

3

4

Page 107: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

BUS

Page 108: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

BUS

Page 109: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

2

BUS

Page 110: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

2

BUS

3

Page 111: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

2

BUS

3

4

Page 112: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

2

BUS

3

45

Page 113: Refactoring Wunderlist. UA Mobile 2016.

3. Use case using an event bus.

Presenter

View

Presentation layer Model

UI domain

db/cache

Use Case

1

2

6

BUS

3

45

Page 114: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER (USE CASE)

Page 115: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER

1

(USE CASE)

Page 116: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER

1

2

(USE CASE)

Page 117: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER

3

1

2

(USE CASE)

Page 118: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER

3

4

1

2

(USE CASE)

Page 119: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

VIEW

PRESENTER

OBSERVER5

3

4

1

2

(USE CASE)

Page 120: Refactoring Wunderlist. UA Mobile 2016.

4. Use case using RxJavaModel

UI domain

db/cache

OBSERVABLE

Presentation layer

6

VIEW

PRESENTER

OBSERVER5

3

4

1

2

(USE CASE)

Page 121: Refactoring Wunderlist. UA Mobile 2016.

Testing?

Page 122: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Page 123: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Presenters don’t have framework dependencies.

Page 124: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Presenters don’t have framework dependencies.

Dependency injection make testing easier

Page 125: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Presenters don’t have framework dependencies.

Use cases are very small and simple.

Dependency injection make testing easier

Page 126: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Presenters don’t have framework dependencies.

Use cases are very small and simple.

We can test now every component independently.

Dependency injection make testing easier

Page 127: Refactoring Wunderlist. UA Mobile 2016.

Testing? Views now don’t have business logic and/or data.

Presenters don’t have framework dependencies.

Use cases are very small and simple.

We can test now every component independently.

Dependency injection make testing easier

Now testing is easy peasy!

Page 128: Refactoring Wunderlist. UA Mobile 2016.

More testing?

Page 129: Refactoring Wunderlist. UA Mobile 2016.

More testing?

VIEW

Espresso

Java + Android

Mockito

JUnit

Page 130: Refactoring Wunderlist. UA Mobile 2016.

More testing?

VIEW

Espresso

Java + Android

Mockito

JUnit

PRESENTER

TestSubscriber

Mockito

JUnit

Java + RxJava

Page 131: Refactoring Wunderlist. UA Mobile 2016.

More testing?

VIEW

Espresso

Java + Android

Mockito

JUnit

PRESENTER

TestSubscriber

Mockito

JUnit

Java + RxJava

USE CASE

TestSubscriber

Mockito

JUnit

Java + RxJava

Page 132: Refactoring Wunderlist. UA Mobile 2016.

More testing?

VIEW

Espresso

Java + Android

Mockito

JUnit

PRESENTER

TestSubscriber

Mockito

JUnit

Java + RxJava

USE CASE

TestSubscriber

Mockito

JUnit

Java + RxJava

UI-DOMAIN

TestSubscriber

Mockito

JUnit

Java + RxJava

Page 133: Refactoring Wunderlist. UA Mobile 2016.

More testing?

VIEW

Espresso

Java + Android

Mockito

JUnit

PRESENTER

TestSubscriber

Mockito

JUnit

Java + RxJava

USE CASE

TestSubscriber

Mockito

JUnit

Java + RxJava

UI-DOMAIN

TestSubscriber

Mockito

JUnit

Java + RxJava

DB/CACHEJava + Android

+ RxJava

Robolectric

Mockito

JUnit

TestSubscriber

Page 134: Refactoring Wunderlist. UA Mobile 2016.

Lessons learned

Page 135: Refactoring Wunderlist. UA Mobile 2016.

Lessons learnedDependency Inversion Principle is key.

Page 136: Refactoring Wunderlist. UA Mobile 2016.

Lessons learnedDependency Inversion Principle is key.

Following SOLID principles makes MVP easy to build.

Page 137: Refactoring Wunderlist. UA Mobile 2016.

Lessons learnedDependency Inversion Principle is key.

Following SOLID principles makes MVP easy to build.

Small use cases define what you want to do.

Page 138: Refactoring Wunderlist. UA Mobile 2016.

Lessons learnedDependency Inversion Principle is key.

Following SOLID principles makes MVP easy to build.

Small use cases define what you want to do.We have different alternatives to fetch data, choose yours.

Page 139: Refactoring Wunderlist. UA Mobile 2016.

Lessons learnedDependency Inversion Principle is key.

Following SOLID principles makes MVP easy to build.

Small use cases define what you want to do.We have different alternatives to fetch data, choose yours.

Decouple components makes testing easier.

Page 140: Refactoring Wunderlist. UA Mobile 2016.

?+CesarValiente @CesarValiente

Thanks!

Page 141: Refactoring Wunderlist. UA Mobile 2016.

?

+CesarValiente @CesarValiente

Thanks!

Page 142: Refactoring Wunderlist. UA Mobile 2016.

License

(cc) 2016 César Valiente. Some rights reserved. This document is distributed under the Creative Commons Attribution-ShareAlike 3.0 license, available in http://creativecommons.org/licenses/by-sa/3.0/

Page 143: Refactoring Wunderlist. UA Mobile 2016.

Image licenses

Wunderlist (Microsoft): permission granted.

Emojis by Emoji One (CC-BY): http://emojione.com/

Iceberg: http://science-all.com/iceberg.html

All images belong to their owners.