build an app with blindfold - britt barak

81
Build An App With Blindfold Britt Barak Droidcon TLV 26.9.16

Upload: droidcontlv

Post on 12-Apr-2017

94 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Build an App with Blindfold - Britt Barak

Build An App With Blindfold

Britt BarakDroidcon TLV

26.9.16

Page 4: Build an App with Blindfold - Britt Barak

Upcoming Events

● Android Beginners - coming on 30/10 !

● Android UI / UX

● Community Hackathon

● Android Performance

● Mentors Program

Page 5: Build an App with Blindfold - Britt Barak

My First Startup

Page 6: Build an App with Blindfold - Britt Barak

“As You Like It” / W. Shakespeare

,All the world’s a stage״

And all the men and women merely players;

They have their exits and their entrances,

And one man in his time plays many parts:״

Page 7: Build an App with Blindfold - Britt Barak

His acts being seven ages. At first, the

infant,

Mewling and puking in the nurse’s arms.

Then the whining schoolboy, with his

satchel

And shining morning face, creeping like

snail

Unwillingly to school. And then the lover,

Sighing like furnace, with a woeful ballad

Made to his mistress’ eyebrow. Then a

soldier,

Full of strange oaths and bearded like the

pard,

Jealous in honor, sudden and quick in

quarrel,

Seeking the bubble reputation

Even in the cannon’s mouth. And then the

justice,

In fair round belly with good capon lined,

With eyes severe and beard of formal cut,

Full of wise saws and modern instances;

And so he plays his part. The sixth age

shifts

Into the lean and slippered pantaloon,

With spectacles on nose and pouch on side;

His youthful hose, well saved, a world too

wide

For his shrunk shank, and his big manly

voice,

Turning again toward childish treble, pipes

And whistles in his sound. Last scene of

all,

That ends this strange eventful history,

Is second childishness and mere oblivion,

Sans teeth, sans eyes, sans taste, sans

everything.

Page 8: Build an App with Blindfold - Britt Barak

“exits and entrances”

The part can change

But there’s always a defined part.

Page 9: Build an App with Blindfold - Britt Barak

File → New Project

Page 10: Build an App with Blindfold - Britt Barak

New Startups

● Uncertainty● Many changes● Low on resources

○ Time○ Developers○ Money

Page 11: Build an App with Blindfold - Britt Barak

We Want To Deliver Fast!

Premature optimizations are bad

1. Mess Grows2. Structure Stays

Page 12: Build an App with Blindfold - Britt Barak

Recipe

1. Big picture - who are the “players”?

2. Small use cases - what are the “parts”?

3. Choose POCs - order “exits and entrances”

Page 13: Build an App with Blindfold - Britt Barak

High Level Structure

Presentation Layer Data LayerDomain Layer

Page 14: Build an App with Blindfold - Britt Barak

High Level Structure

Presentation Layer

● View● ViewEntity● Presenter

→ Framework

Data Layer

● Repository● Entity

→ Java

Domain Layer

● Interactor● Use case

→ Java

Page 15: Build an App with Blindfold - Britt Barak

Example : Add Chat Feature To App

Page 16: Build an App with Blindfold - Britt Barak

Big Picture - The Players

● Add chat feature to the app● Chat between groups of members

Page 17: Build an App with Blindfold - Britt Barak

Separation

App Module

Chat Module

Page 18: Build an App with Blindfold - Britt Barak

Why New Module?

- Encapsulate implementation- Easy to replace- Easy to reuse

Page 19: Build an App with Blindfold - Britt Barak

Structure:

Page 20: Build an App with Blindfold - Britt Barak

Presentation Layer - App Module

Page 21: Build an App with Blindfold - Britt Barak

Data Layer - Chat Module

let‘s talk about the data structure.

Page 22: Build an App with Blindfold - Britt Barak

Firebase DB

- Easy. - noSQL- Flat- Get data by reference

- ref/messages/chat_one_id

Page 23: Build an App with Blindfold - Britt Barak

Don’t - Nest{

"chats": {

"chatOneId": {

"title": "As You Like It",

"messages": {

"msg1Id": { "sender": "melancholyJaques", "message": "All world’s a stage." },

"msg2Id": { ... },

// a very long list of messages

}

},

"chatTwoId": { ... } }}

Page 24: Build an App with Blindfold - Britt Barak

Do - Flat : Chats{

"chats": {

"chatOneId": {

"title": "As You Like It"

},

"chatTwoId": { ... },

"chatThreeId": { ... }

}

Page 25: Build an App with Blindfold - Britt Barak

Do - Flat : Members{

"members": {

"chatOneId": {

"melancholyJaques": true,

"dukeSenior": true,

},

"chatTwoId": { ... },

"chatThreeId": { ... }

},

Page 26: Build an App with Blindfold - Britt Barak

Do - Flat : Users{

"users": {

"melancholyJaques": {

"name": Melancholy Jaques",

"photoId": "23h42",

"chats": {

"chatOneId": true,

"chatTwoId": true

}

},

...

},

Page 27: Build an App with Blindfold - Britt Barak

Do - Flat : Messages "messages": {

"chatOneId": {

"msg1Id": {

"sender": "melancholyJaques",

"message": "All world’s a stage.",

"timestamp": 1459361875337

},

"msg2Id": { ... },

// a very long list of messages

},

"chatTwoId": { ... },

}

}

Page 28: Build an App with Blindfold - Britt Barak

On my code

Chat module: individual separate pieces:

- Chats Repository- Members Repository- Users Repository- Messages Repository

Page 29: Build an App with Blindfold - Britt Barak

Repository (Data Layer)

Part - provide and update data.

Encapsulates implementation.

Page 30: Build an App with Blindfold - Britt Barak

public class UsersRepo implements IUsersRepository {

MyFirebaseDBClient firebaseClient;

@Override public void getChatIDs(Callback callback) { firebaseClient.fetchChats(callback); }

Page 31: Build an App with Blindfold - Britt Barak

public class UsersRepo implements IUsersRepository {

MyFirebaseDBClient firebaseClient; MyCache cache;

@Override public void getChatIDs(Callback callback) { if (cache.hasChats()) { callback.success(cache.getChatIDs()); } else { firebaseClient.fetchChatIDs(callback); } }

Page 32: Build an App with Blindfold - Britt Barak

public class UsersRepo implements IUsersRepository {

MyFirebaseDBClient firebaseClient; MyCache cache; ChatsLocalDB localDB;

@Override public void getChatIDs(Callback callback) { if (cache.hasChatIDs()) { callback.success(cache.getChatIDs()); } else if (localDB.hasChatIDs()) { callback.success(localDB.getChatIDs()); } else { firebaseClient.fetchChatIDs(callback); } }

Page 33: Build an App with Blindfold - Britt Barak

public class UsersRepo implements IUsersRepository {

MyApiClient apiClient; MyCache cache; ChatsLocalDB localDB;

@Override public void getChatIDs(Callback callback) { if (cache.hasChatIDs()) { callback.success(cache.getChatIDs()); } else if (localDB.hasChatIDs()) { callback.success(localDB.getChatIDs()); } else { apiClient.fetchChatIDs(callback); } }

Page 34: Build an App with Blindfold - Britt Barak

Recipe

1. Big picture - who are the “players”?

2. Small use cases - what are the “parts”?

3. Choose POCs - order “exits and entrances”

Page 35: Build an App with Blindfold - Britt Barak

Domain layer - Use Cases

Use cases / interactors

What does the app do? What are its use cases?

Page 36: Build an App with Blindfold - Britt Barak

Example: getChatsPreviewList (use case)

Page 37: Build an App with Blindfold - Britt Barak

Get user’s chat IDs

Get chat’s info

Chats Repo

Get chats preview list

Chat list activity

Users Repo

Get Chat Preview List

Page 38: Build an App with Blindfold - Britt Barak

Get chats preview list

List<Chat>List<String>

ChatRaw

Get Chat Preview List

List<ChatRaw>

Page 39: Build an App with Blindfold - Britt Barak

Get Chat Preview Listpublic class GetChatPreviewListImpl implements GetChatsPreviewList {

public void execute(final Callback<List<Chat>> callback) {

usersRepo.getChatIDs(new Callback<List<String>>() {

@Override

public void success(List<String> chatIDs) {

chatsRepo.getChats(new Callback<List<RawChat>>() {

@Override

public void success(List<RawChat> rawChats) {

List<Chat> chats = proccessChats(rawChats);

callback.success(chats);

}

});

}

});

}

Page 40: Build an App with Blindfold - Britt Barak

Get chats preview list

Get chat members

Get chat messags ….

App Module Will Ask For More

Chat list activity

Page 41: Build an App with Blindfold - Britt Barak

Recipe

1. Big picture - who are the “players”?

2. Small use cases - what are the “parts”?

3. Choose POCs - order “exits and entrances”

Page 42: Build an App with Blindfold - Britt Barak

Choose POC

- Play the App Module Part:

- Forget the chat implementation!

- ChatClient - POC class

Page 43: Build an App with Blindfold - Britt Barak

Chat Client

Get chats preview list

Get chat members

Get chat messags ….

Choose POC

App Module

Page 44: Build an App with Blindfold - Britt Barak

Get Chat Preview List

Chat list activity

Chat Client

Users Repo

Chats Repo

userId chatIds

Page 45: Build an App with Blindfold - Britt Barak

Demand

On chats preview list:

show last message

Page 46: Build an App with Blindfold - Britt Barak

Get Chat Preview List 2

Too messy. Too many listeners and threads. Too much time.

Chat Client

Users Repo

Chat list activity

Chats Repo

userId chatIds

Msgs Repo

Get chats preview list

Page 47: Build an App with Blindfold - Britt Barak

Get Chat Preview List 3

Add data straight to chat Info node"chats": {

"chatOneId": {

"title": "As You Like It"

"lastMessage": "All world’s a stage" },

"chatTwoId": { ... },

"chatThreeId": { ... }

},

Page 48: Build an App with Blindfold - Britt Barak

Get Chat Preview List 3

Too messy. Too many listeners and threads. Too much time.

Chat Client

Users Repo

Chat list activity

Chats Repo

userId chatIdsGet chats preview list

Page 49: Build an App with Blindfold - Britt Barak

But now: more work when sending a message

Page 50: Build an App with Blindfold - Britt Barak

Send : Before

Chat activity

Chat Client

Msgs RepoSend

Page 51: Build an App with Blindfold - Britt Barak

Send : After

Chat activity

Chat Client

Msgs RepoSend

Chats Repo

Page 52: Build an App with Blindfold - Britt Barak

Demand

Message visibility per user.

“Last message”

isn’t general anymore.

Page 53: Build an App with Blindfold - Britt Barak

Structure - Message

"message1": {

...

"visibleTo": {

"userId1": true,

"userId2": true

},

}

Page 54: Build an App with Blindfold - Britt Barak

Structure - Personal Chat Info

Chats

General Info

Personal Info

title Last msg

Page 55: Build an App with Blindfold - Britt Barak

Personal Chat Info Node{

"personalInfo": {

"melancholyJaques": {

"lastMessage": All world’s a stage",

"timestamp": 1459361875337

},

...

},

Page 56: Build an App with Blindfold - Britt Barak

Get Chat Preview List 4

Too messy. Too many listeners and threads. Too much time.

Chat Client

Users Repo

Chat list activity

userId chatIdsGet chats preview list

personal Info Repo

general Info Repo

Page 57: Build an App with Blindfold - Britt Barak

Send : Update Per User

App Module

Chat Client

Msgs Repo

userId chatIds

personal Info Repo

Send

Is visible?

Page 58: Build an App with Blindfold - Britt Barak

But I have many recipients….

Takes long to update each user repo...

Page 59: Build an App with Blindfold - Britt Barak

Send :

Send

Message Repo

FCM

Page 60: Build an App with Blindfold - Britt Barak

Receive :

Send Receive

Personal Info Repo

Message Repo

FCM

Page 61: Build an App with Blindfold - Britt Barak

Give the part to a differenet Player

Page 62: Build an App with Blindfold - Britt Barak

Sum Up

- Small defined use cases:- Easy to maintain- Easy to change- Easy to test- Mix and match

- “Play the part” → create POC class- Encapsulate implementation- Organize code

- Be mindful to what needs a change

Page 63: Build an App with Blindfold - Britt Barak

Example changing the part

Page 64: Build an App with Blindfold - Britt Barak
Page 65: Build an App with Blindfold - Britt Barak

FCM Usages

- Notify user- Update DB- Update UI- Fetch new data- Start service- ……...

Page 66: Build an App with Blindfold - Britt Barak

How Does It Work?public class MyFCMService extends FirebaseMessagingService {

@Override

public void onMessageReceived(RemoteMessage remoteMessage) {

//...

}

}

Page 67: Build an App with Blindfold - Britt Barak

Remote Message Part

Notify about an event.

Page 68: Build an App with Blindfold - Britt Barak

FCM Handling

Type per message

RemoteMessage

Data….< “type” , “new_chat_message” >….

Page 69: Build an App with Blindfold - Britt Barak

FCM Handlingpublic class MyFCMService extends FirebaseMessagingService {

@Override

public void onMessageReceived(RemoteMessage remoteMessage) {

String type = data.get(StaticKeys.KEY_TYPE);

switch (type) {

//....

}

}

}

Page 70: Build an App with Blindfold - Britt Barak

It Worked Great...

We added up more and more events…..

- New chat message- New member added- Member removed- New data available- ………………..

Page 71: Build an App with Blindfold - Britt Barak

…for some time :-/

- Too many event types

- Too complex code

- Hard to change

- Hard to combine

- Sometimes one usecase represented multiple event types and forced few fcm messages

- The ugly switch-case...

Page 72: Build an App with Blindfold - Britt Barak

Demand

- Easily support new types- Change remotely

Page 73: Build an App with Blindfold - Britt Barak

Wait….

Take a step back.

What did we mean to do?

1. Notifying users2. Update data / ui3. Update DB

Page 74: Build an App with Blindfold - Britt Barak

Remote Message Part

Notify an event.

Notify about stuff that need to be done.

Page 75: Build an App with Blindfold - Britt Barak

Handle By Data Attributes

RemoteMessage

Data….<“notify” , “true” ><“title” , “New Message” ><“icon” , “ic_chat” ><“click_action”,

“com.figure8.app.action.OPEN_CHAT”><“refresh_members”, chat_id>….

Page 76: Build an App with Blindfold - Britt Barak

Handle By Data Attributes

Messaging Service

Notif Producer

Data Refresher

DB Updater

Remote Message

Remote Message

Page 77: Build an App with Blindfold - Britt Barak

Pros

- Flexible

- Update remotely

- Test:

- Test the data producer

- Test the data handler

Page 78: Build an App with Blindfold - Britt Barak

What Did We Do?

Gave the component a different part.

Page 79: Build an App with Blindfold - Britt Barak

“exits and entrances”

The part can change

But there’s always a defined part.

Page 80: Build an App with Blindfold - Britt Barak

Questions?

Page 81: Build an App with Blindfold - Britt Barak

Thank you :)