SlideShare a Scribd company logo
1 of 39
Download to read offline
Home Improvement:
Architecture & Kotlin
Jorge D. Ortiz-Fuentes
@jdortiz
#AdvArchMobile
A Canonical
Examples
Production
#AdvArchMobile
Disclaimer
#AdvArchMobile
Agenda
★ Architecture
★ Kotlin
★ Recap
Clean
Architecture
Persistance FW
View
Network
LocationFW
Presenter
Entity Gateway
Clean Architecture
Interactor
Entity
Dependency Inversion
Principle
High Level Low LevelAbstraction
Low Level
#AdvArchMobile
Respectful Criticism
about some
Opinionated
Decisions
#AdvArchMobile
Architecture Components
★ Awesome starting point
★ View Models (inner layer) depend on the
SDK:AndroidViewModel (outer layer)
Kotlin
#AdvArchMobile
Kotlin
★ Conciseness
★ Data Classes
★ Extensions
★ Property Delegation
★ Sealed Classes
Conciseness
#AdvArchMobile
Conciseness (code)
@Module public class ProgrammersListModule {

private ProgrammersListActivity activity;



public ProgrammersListModule(ProgrammersListActivity activity)
{ this.activity = activity; }



@Provides ProgrammersListPresenter
provideProgrammersListPresenter(ShowProgrammersListUseCase useCase) {

ProgrammersListPresenter presenter = new
ProgrammersListPresenter(useCase);

useCase.setPresenter(presenter);

presenter.setView(activity);

return presenter;

}



@Provides ProgrammersListConnector provideProgrammersListConnector()
{

return new ProgrammersListConnector(activity);

}

}
#AdvArchMobile
@Module class ProgrammersListModule(private val activity: ProgrammersListActivity) {

@Provides fun provideProgrammersListPresenter(useCase:
ShowProgrammersListUseCase): ProgrammersListPresenter =

ProgrammersListPresenter(useCase = useCase).apply {

useCase.presenter = this

view = activity

}



@Provides fun provideProgrammersListConnector() = ProgrammersListConnector(view
= activity)

}
Conciseness (code)
@Module public class ProgrammersListModule {

private ProgrammersListActivity activity;



public ProgrammersListModule(ProgrammersListActivity activity) { this.activity = activity; }



@Provides ProgrammersListPresenter provideProgrammersListPresenter(ShowProgrammersListUseCase useCase) {

ProgrammersListPresenter presenter = new ProgrammersListPresenter(useCase);

useCase.setPresenter(presenter);

presenter.setView(activity);

return presenter;

}



@Provides ProgrammersListConnector provideProgrammersListConnector() {

return new ProgrammersListConnector(activity);

}

}
#AdvArchMobile
@Module class ProgrammersListModule(private val
activity: ProgrammersListActivity) {

@Provides fun
provideProgrammersListPresenter(useCase:
ShowProgrammersListUseCase): ProgrammersListPresenter =

ProgrammersListPresenter(useCase =
useCase).apply {

useCase.presenter = this

view = activity

}



@Provides fun provideProgrammersListConnector() =
ProgrammersListConnector(view = activity)

}
Conciseness (code)
#AdvArchMobile
Conciseness (test)
@Test public void
itemIsConfiguredWithNameOfFetchedProgrammer() {

ProgrammersListItemView item =
Mockito.mock(ProgrammersListItemView.class);

List<ProgrammerResponse> data = new
ArrayList<ProgrammerResponse>() {{

add(TestUtils.createMainProgrammerResponse());

add(TestUtils.createAltProgrammerResponse());

}};

ArgumentCaptor<String> captor =
ArgumentCaptor.forClass(String.class);

sut.presentProgrammers(data);

sut.configureItem(item, 1);

verify(item).displayName(captor.capture());

assertEquals(TestData.programmerAltFullName,
captor.getValue());

}
#AdvArchMobile
@Test fun itemIsConfiguredWithNameOfFetchedProgrammer() {

val item = mock<ProgrammersListItemView>()

val data = listOf(TestData.createMainProgrammerResponse(),

TestData.createAltProgrammerResponse())

sut.present(programmers = data)



sut.configureItem(item, 1)



argumentCaptor<String>().apply {

verify(item).displayName(capture())

assertEquals(TestData.altFullName, lastValue)

}

}
Conciseness
@Test public void itemIsConfiguredWithNameOfFetchedProgrammer() {

ProgrammersListItemView item = Mockito.mock(ProgrammersListItemView.class);

List<ProgrammerResponse> data = new ArrayList<ProgrammerResponse>() {{

add(TestUtils.createMainProgrammerResponse());

add(TestUtils.createAltProgrammerResponse());

}};

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

sut.presentProgrammers(data);

sut.configureItem(item, 1);

verify(item).displayName(captor.capture());

assertEquals(TestData.programmerAltFullName, captor.getValue());

}
#AdvArchMobile
@Test fun itemIsConfiguredWithNameOfFetchedProgrammer() {

val item = mock<ProgrammersListItemView>()

val data =
listOf(TestData.createMainProgrammerResponse(),

TestData.createAltProgrammerResponse())

sut.present(programmers = data)



sut.configureItem(item, 1)



argumentCaptor<String>().apply {

verify(item).displayName(capture())

assertEquals(TestData.altFullName, lastValue)

}

}
Conciseness
Data Classes
#AdvArchMobile
Entities
data class Programmer(
val firstName: String,
val lastName: String,
val emacs: Int, val caffeine: Int,

val realProgrammerRating: Int,
val interviewDate: Date,
val favorite: Boolean) {

val fullName: String

get() = "$firstName $lastName"

}
#AdvArchMobile
But
★ Not a value type
★ No defensive copy
#AdvArchMobile
Defensive Copying
data class Entity
private constructor(var private _date: Date) {
companion object {
fun create(date: Date): Entity =
Entity(_date = Date(date.time))
}
var date: Date = Date(_date.time)
get() = Date(field.time)
set(value) {
field = Date(date.time)
}
}
Extensions
#AdvArchMobile
Presentation Logic
fun Date.relativeDateFormat(origin: Date = Date()): String {

fun differenceInDays(date1: Date, date2: Date): Long {

val MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000

return (date1.time - date2.time) /
MILLISECONDS_IN_A_DAY

}



val daysAgo = differenceInDays(origin, this)

return when {

daysAgo < 0 -> "In the future"

daysAgo < 1 -> "Today"

daysAgo < 7 -> "Less than a week ago"

daysAgo < 30 -> "Less than a month ago"

daysAgo < 365 -> "Less than a year ago"

else -> "Long time ago"

}

}
#AdvArchMobile
But
★ A class cannot implement an interface using
extensions
★ Methods are declared independently
Property Delegation
#AdvArchMobile
Observation
data class ProductRequest(var name: String, var units: Int)
class Presenter() {
var request: ProductRequest by Delegates.observable(ProductRequest(name="",
units=0)) {
prop, old, new ->
requestChanged()
}
fun requestChanged() { print("Request: $request”) }
fun changeDoesNotTrigger() {
request.name = "Something"
request.units = 1
}
fun completeChangeThatTriggers() {
request = ProductRequest(name="Else", units= 2)
}
}
#AdvArchMobile
Delegating Reference
Type
class WeakReferenceHolder<T, U> {

private var propertyRef: WeakReference<U>? = null



operator fun getValue(t: T, property: KProperty<*>): U? =
propertyRef?.get()



operator fun setValue(t: T, property: KProperty<*>, newValue: U?)
{

propertyRef = if (newValue != null) {

WeakReference(newValue)

} else {

null

}

}

}

var view: ProgrammersListView? by
WeakReferenceHolder<ProgrammersListPresenter, ProgrammersListView>()
Sealed Classes
Enum
considered
harmful
#AdvArchMobile
Avoid Enums
★ Space
★ Performance
Sealed
Classes
Too!
#AdvArchMobile
Don’t*
sealed class Interactor {
class ShowProducts(val completion: ()-
>Unit): Interactor() {}
class DeleteProduct(id: String,
completion: ()->Unit) {}
}
when (interactor) {
is ShowProducts -> …
}
#AdvArchMobile
Do
sealed class Result<V: Any, E:
Exception> {
class Success<V: Any, E:
Exception>(val value: V) : Result<V,
E>() {//…}
class Failure<V: Any, E:
Exception>(val error: E) : Result<V,
E>() {//…}
}
Recap
#AdvArchMobile
Recap
★ Kotlin makes advanced architectures easier
★ Learn your options and choose
★ Still learning the idioms, work with the
community
Thank
You!
@jdortiz
#AdvArchMobile

More Related Content

What's hot

Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4ICS
 
Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh
Building Native Apps- A Digital Canvas for Coders and Designers with Walter LuhBuilding Native Apps- A Digital Canvas for Coders and Designers with Walter Luh
Building Native Apps- A Digital Canvas for Coders and Designers with Walter LuhFITC
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programmingICS
 
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Marius Bugge Monsen
 
Practical Model View Programming
Practical Model View ProgrammingPractical Model View Programming
Practical Model View ProgrammingMarius Bugge Monsen
 
The Next Generation Qt Item Views
The Next Generation Qt Item ViewsThe Next Generation Qt Item Views
The Next Generation Qt Item Viewsaccount inactive
 
Immutable Libraries for React
Immutable Libraries for ReactImmutable Libraries for React
Immutable Libraries for Reactstbaechler
 
Petri Niemi Qt Advanced Part 1
Petri Niemi Qt Advanced Part 1Petri Niemi Qt Advanced Part 1
Petri Niemi Qt Advanced Part 1NokiaAppForum
 
CodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilderCodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilderAndres Almiray
 
AngularJs in Las Palmas de GC
AngularJs in Las Palmas de GCAngularJs in Las Palmas de GC
AngularJs in Las Palmas de GCMarcin Wosinek
 
Practical QML - Key Navigation, Dynamic Language and Theme Change
Practical QML - Key Navigation, Dynamic Language and Theme ChangePractical QML - Key Navigation, Dynamic Language and Theme Change
Practical QML - Key Navigation, Dynamic Language and Theme ChangeBurkhard Stubert
 
Ken 20150306 心得分享
Ken 20150306 心得分享Ken 20150306 心得分享
Ken 20150306 心得分享LearningTech
 
Integrating React.js Into a PHP Application: Dutch PHP 2019
Integrating React.js Into a PHP Application: Dutch PHP 2019Integrating React.js Into a PHP Application: Dutch PHP 2019
Integrating React.js Into a PHP Application: Dutch PHP 2019Andrew Rota
 
C# Advanced L02-Operator Overloading+Indexers+UD Conversion
C# Advanced L02-Operator Overloading+Indexers+UD ConversionC# Advanced L02-Operator Overloading+Indexers+UD Conversion
C# Advanced L02-Operator Overloading+Indexers+UD ConversionMohammad Shaker
 
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)Andrew Rota
 
Oops lab manual2
Oops lab manual2Oops lab manual2
Oops lab manual2Mouna Guru
 
Receipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google AssistantReceipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google AssistantOrestes Carracedo
 

What's hot (20)

Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh
Building Native Apps- A Digital Canvas for Coders and Designers with Walter LuhBuilding Native Apps- A Digital Canvas for Coders and Designers with Walter Luh
Building Native Apps- A Digital Canvas for Coders and Designers with Walter Luh
 
Qt Widget In-Depth
Qt Widget In-DepthQt Widget In-Depth
Qt Widget In-Depth
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programming
 
Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)Practical Model View Programming (Roadshow Version)
Practical Model View Programming (Roadshow Version)
 
Practical Model View Programming
Practical Model View ProgrammingPractical Model View Programming
Practical Model View Programming
 
The Next Generation Qt Item Views
The Next Generation Qt Item ViewsThe Next Generation Qt Item Views
The Next Generation Qt Item Views
 
Immutable Libraries for React
Immutable Libraries for ReactImmutable Libraries for React
Immutable Libraries for React
 
Petri Niemi Qt Advanced Part 1
Petri Niemi Qt Advanced Part 1Petri Niemi Qt Advanced Part 1
Petri Niemi Qt Advanced Part 1
 
CodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilderCodeMash - Building Rich Apps with Groovy SwingBuilder
CodeMash - Building Rich Apps with Groovy SwingBuilder
 
AngularJs in Las Palmas de GC
AngularJs in Las Palmas de GCAngularJs in Las Palmas de GC
AngularJs in Las Palmas de GC
 
Practical QML - Key Navigation, Dynamic Language and Theme Change
Practical QML - Key Navigation, Dynamic Language and Theme ChangePractical QML - Key Navigation, Dynamic Language and Theme Change
Practical QML - Key Navigation, Dynamic Language and Theme Change
 
Ken 20150306 心得分享
Ken 20150306 心得分享Ken 20150306 心得分享
Ken 20150306 心得分享
 
Integrating React.js Into a PHP Application: Dutch PHP 2019
Integrating React.js Into a PHP Application: Dutch PHP 2019Integrating React.js Into a PHP Application: Dutch PHP 2019
Integrating React.js Into a PHP Application: Dutch PHP 2019
 
C# Advanced L02-Operator Overloading+Indexers+UD Conversion
C# Advanced L02-Operator Overloading+Indexers+UD ConversionC# Advanced L02-Operator Overloading+Indexers+UD Conversion
C# Advanced L02-Operator Overloading+Indexers+UD Conversion
 
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)Performant APIs with GraphQL and PHP (Dutch PHP 2019)
Performant APIs with GraphQL and PHP (Dutch PHP 2019)
 
Oops lab manual2
Oops lab manual2Oops lab manual2
Oops lab manual2
 
Receipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google AssistantReceipt processing with Google Cloud Platform and the Google Assistant
Receipt processing with Google Cloud Platform and the Google Assistant
 
Treinamento Qt básico - aula III
Treinamento Qt básico - aula IIITreinamento Qt básico - aula III
Treinamento Qt básico - aula III
 
Why Grails?
Why Grails?Why Grails?
Why Grails?
 

Similar to Home Improvement: Architecture & Kotlin for Mobile Apps

Cleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsCleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsDebora Gomez Bertoli
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Nicolas HAAN
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Max Pronko
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtAlina Vilk
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rockmartincronje
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Appcelerator droidcon15 TLV
Appcelerator droidcon15 TLVAppcelerator droidcon15 TLV
Appcelerator droidcon15 TLVYishaiBrown
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolboxShem Magnezi
 
MobiConf 2018 | Room: an SQLite object mapping library
MobiConf 2018 | Room: an SQLite object mapping library MobiConf 2018 | Room: an SQLite object mapping library
MobiConf 2018 | Room: an SQLite object mapping library Magda Miu
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularIlia Idakiev
 
GDG Kuwait - Modern android development
GDG Kuwait - Modern android developmentGDG Kuwait - Modern android development
GDG Kuwait - Modern android developmentGDGKuwaitGoogleDevel
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
ECMAScript.Next ECMAScipt 6
ECMAScript.Next ECMAScipt 6ECMAScript.Next ECMAScipt 6
ECMAScript.Next ECMAScipt 6Kevin DeRudder
 
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationLotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationSean Burgess
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化Tomoharu ASAMI
 

Similar to Home Improvement: Architecture & Kotlin for Mobile Apps (20)

Cleaning your architecture with android architecture components
Cleaning your architecture with android architecture componentsCleaning your architecture with android architecture components
Cleaning your architecture with android architecture components
 
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
Comment développer une application mobile en 8 semaines - Meetup PAUG 24-01-2023
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2
 
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArtArchitecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rock
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Appcelerator droidcon15 TLV
Appcelerator droidcon15 TLVAppcelerator droidcon15 TLV
Appcelerator droidcon15 TLV
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
MobiConf 2018 | Room: an SQLite object mapping library
MobiConf 2018 | Room: an SQLite object mapping library MobiConf 2018 | Room: an SQLite object mapping library
MobiConf 2018 | Room: an SQLite object mapping library
 
Building Reusable Custom Elements With Angular
Building Reusable Custom Elements With AngularBuilding Reusable Custom Elements With Angular
Building Reusable Custom Elements With Angular
 
Green dao
Green daoGreen dao
Green dao
 
GDG Kuwait - Modern android development
GDG Kuwait - Modern android developmentGDG Kuwait - Modern android development
GDG Kuwait - Modern android development
 
Dartprogramming
DartprogrammingDartprogramming
Dartprogramming
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
ECMAScript.Next ECMAScipt 6
ECMAScript.Next ECMAScipt 6ECMAScript.Next ECMAScipt 6
ECMAScript.Next ECMAScipt 6
 
Es.next
Es.nextEs.next
Es.next
 
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationLotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化
 

More from Jorge Ortiz

Tell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsTell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsJorge Ortiz
 
Unit Test your Views
Unit Test your ViewsUnit Test your Views
Unit Test your ViewsJorge Ortiz
 
Control your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritControl your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritJorge Ortiz
 
Kata gilded rose en Golang
Kata gilded rose en GolangKata gilded rose en Golang
Kata gilded rose en GolangJorge Ortiz
 
CYA: Cover Your App
CYA: Cover Your AppCYA: Cover Your App
CYA: Cover Your AppJorge Ortiz
 
Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forwardJorge Ortiz
 
201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SGJorge Ortiz
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowersJorge Ortiz
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive AppsJorge Ortiz
 
iOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editioniOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editionJorge Ortiz
 
Android clean architecture workshop 3h edition
Android clean architecture workshop 3h editionAndroid clean architecture workshop 3h edition
Android clean architecture workshop 3h editionJorge Ortiz
 
To Protect & To Serve
To Protect & To ServeTo Protect & To Serve
To Protect & To ServeJorge Ortiz
 
Clean architecture workshop
Clean architecture workshopClean architecture workshop
Clean architecture workshopJorge Ortiz
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from MarsJorge Ortiz
 
Why the Dark Side should use Swift and a SOLID Architecture
Why the Dark Side should use Swift and a SOLID ArchitectureWhy the Dark Side should use Swift and a SOLID Architecture
Why the Dark Side should use Swift and a SOLID ArchitectureJorge Ortiz
 
Dependence day insurgence
Dependence day insurgenceDependence day insurgence
Dependence day insurgenceJorge Ortiz
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowersJorge Ortiz
 
TDD for the masses
TDD for the massesTDD for the masses
TDD for the massesJorge Ortiz
 
7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOSJorge Ortiz
 
Building for perfection
Building for perfectionBuilding for perfection
Building for perfectionJorge Ortiz
 

More from Jorge Ortiz (20)

Tell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature FlagsTell Me Quando - Implementing Feature Flags
Tell Me Quando - Implementing Feature Flags
 
Unit Test your Views
Unit Test your ViewsUnit Test your Views
Unit Test your Views
 
Control your Voice like a Bene Gesserit
Control your Voice like a Bene GesseritControl your Voice like a Bene Gesserit
Control your Voice like a Bene Gesserit
 
Kata gilded rose en Golang
Kata gilded rose en GolangKata gilded rose en Golang
Kata gilded rose en Golang
 
CYA: Cover Your App
CYA: Cover Your AppCYA: Cover Your App
CYA: Cover Your App
 
Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forward
 
201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG201710 Fly Me to the View - iOS Conf SG
201710 Fly Me to the View - iOS Conf SG
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowers
 
Architecting Alive Apps
Architecting Alive AppsArchitecting Alive Apps
Architecting Alive Apps
 
iOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h editioniOS advanced architecture workshop 3h edition
iOS advanced architecture workshop 3h edition
 
Android clean architecture workshop 3h edition
Android clean architecture workshop 3h editionAndroid clean architecture workshop 3h edition
Android clean architecture workshop 3h edition
 
To Protect & To Serve
To Protect & To ServeTo Protect & To Serve
To Protect & To Serve
 
Clean architecture workshop
Clean architecture workshopClean architecture workshop
Clean architecture workshop
 
Escape from Mars
Escape from MarsEscape from Mars
Escape from Mars
 
Why the Dark Side should use Swift and a SOLID Architecture
Why the Dark Side should use Swift and a SOLID ArchitectureWhy the Dark Side should use Swift and a SOLID Architecture
Why the Dark Side should use Swift and a SOLID Architecture
 
Dependence day insurgence
Dependence day insurgenceDependence day insurgence
Dependence day insurgence
 
Architectural superpowers
Architectural superpowersArchitectural superpowers
Architectural superpowers
 
TDD for the masses
TDD for the massesTDD for the masses
TDD for the masses
 
7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS7 Stages of Unit Testing in iOS
7 Stages of Unit Testing in iOS
 
Building for perfection
Building for perfectionBuilding for perfection
Building for perfection
 

Recently uploaded

What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 

Recently uploaded (20)

What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 

Home Improvement: Architecture & Kotlin for Mobile Apps

  • 1. Home Improvement: Architecture & Kotlin Jorge D. Ortiz-Fuentes @jdortiz
  • 3.
  • 5.
  • 9. Dependency Inversion Principle High Level Low LevelAbstraction Low Level
  • 11. #AdvArchMobile Architecture Components ★ Awesome starting point ★ View Models (inner layer) depend on the SDK:AndroidViewModel (outer layer)
  • 13. #AdvArchMobile Kotlin ★ Conciseness ★ Data Classes ★ Extensions ★ Property Delegation ★ Sealed Classes
  • 15. #AdvArchMobile Conciseness (code) @Module public class ProgrammersListModule {
 private ProgrammersListActivity activity;
 
 public ProgrammersListModule(ProgrammersListActivity activity) { this.activity = activity; }
 
 @Provides ProgrammersListPresenter provideProgrammersListPresenter(ShowProgrammersListUseCase useCase) {
 ProgrammersListPresenter presenter = new ProgrammersListPresenter(useCase);
 useCase.setPresenter(presenter);
 presenter.setView(activity);
 return presenter;
 }
 
 @Provides ProgrammersListConnector provideProgrammersListConnector() {
 return new ProgrammersListConnector(activity);
 }
 }
  • 16. #AdvArchMobile @Module class ProgrammersListModule(private val activity: ProgrammersListActivity) {
 @Provides fun provideProgrammersListPresenter(useCase: ShowProgrammersListUseCase): ProgrammersListPresenter =
 ProgrammersListPresenter(useCase = useCase).apply {
 useCase.presenter = this
 view = activity
 }
 
 @Provides fun provideProgrammersListConnector() = ProgrammersListConnector(view = activity)
 } Conciseness (code) @Module public class ProgrammersListModule {
 private ProgrammersListActivity activity;
 
 public ProgrammersListModule(ProgrammersListActivity activity) { this.activity = activity; }
 
 @Provides ProgrammersListPresenter provideProgrammersListPresenter(ShowProgrammersListUseCase useCase) {
 ProgrammersListPresenter presenter = new ProgrammersListPresenter(useCase);
 useCase.setPresenter(presenter);
 presenter.setView(activity);
 return presenter;
 }
 
 @Provides ProgrammersListConnector provideProgrammersListConnector() {
 return new ProgrammersListConnector(activity);
 }
 }
  • 17. #AdvArchMobile @Module class ProgrammersListModule(private val activity: ProgrammersListActivity) {
 @Provides fun provideProgrammersListPresenter(useCase: ShowProgrammersListUseCase): ProgrammersListPresenter =
 ProgrammersListPresenter(useCase = useCase).apply {
 useCase.presenter = this
 view = activity
 }
 
 @Provides fun provideProgrammersListConnector() = ProgrammersListConnector(view = activity)
 } Conciseness (code)
  • 18. #AdvArchMobile Conciseness (test) @Test public void itemIsConfiguredWithNameOfFetchedProgrammer() {
 ProgrammersListItemView item = Mockito.mock(ProgrammersListItemView.class);
 List<ProgrammerResponse> data = new ArrayList<ProgrammerResponse>() {{
 add(TestUtils.createMainProgrammerResponse());
 add(TestUtils.createAltProgrammerResponse());
 }};
 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
 sut.presentProgrammers(data);
 sut.configureItem(item, 1);
 verify(item).displayName(captor.capture());
 assertEquals(TestData.programmerAltFullName, captor.getValue());
 }
  • 19. #AdvArchMobile @Test fun itemIsConfiguredWithNameOfFetchedProgrammer() {
 val item = mock<ProgrammersListItemView>()
 val data = listOf(TestData.createMainProgrammerResponse(),
 TestData.createAltProgrammerResponse())
 sut.present(programmers = data)
 
 sut.configureItem(item, 1)
 
 argumentCaptor<String>().apply {
 verify(item).displayName(capture())
 assertEquals(TestData.altFullName, lastValue)
 }
 } Conciseness @Test public void itemIsConfiguredWithNameOfFetchedProgrammer() {
 ProgrammersListItemView item = Mockito.mock(ProgrammersListItemView.class);
 List<ProgrammerResponse> data = new ArrayList<ProgrammerResponse>() {{
 add(TestUtils.createMainProgrammerResponse());
 add(TestUtils.createAltProgrammerResponse());
 }};
 ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
 sut.presentProgrammers(data);
 sut.configureItem(item, 1);
 verify(item).displayName(captor.capture());
 assertEquals(TestData.programmerAltFullName, captor.getValue());
 }
  • 20. #AdvArchMobile @Test fun itemIsConfiguredWithNameOfFetchedProgrammer() {
 val item = mock<ProgrammersListItemView>()
 val data = listOf(TestData.createMainProgrammerResponse(),
 TestData.createAltProgrammerResponse())
 sut.present(programmers = data)
 
 sut.configureItem(item, 1)
 
 argumentCaptor<String>().apply {
 verify(item).displayName(capture())
 assertEquals(TestData.altFullName, lastValue)
 }
 } Conciseness
  • 22. #AdvArchMobile Entities data class Programmer( val firstName: String, val lastName: String, val emacs: Int, val caffeine: Int,
 val realProgrammerRating: Int, val interviewDate: Date, val favorite: Boolean) {
 val fullName: String
 get() = "$firstName $lastName"
 }
  • 23. #AdvArchMobile But ★ Not a value type ★ No defensive copy
  • 24. #AdvArchMobile Defensive Copying data class Entity private constructor(var private _date: Date) { companion object { fun create(date: Date): Entity = Entity(_date = Date(date.time)) } var date: Date = Date(_date.time) get() = Date(field.time) set(value) { field = Date(date.time) } }
  • 26. #AdvArchMobile Presentation Logic fun Date.relativeDateFormat(origin: Date = Date()): String {
 fun differenceInDays(date1: Date, date2: Date): Long {
 val MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000
 return (date1.time - date2.time) / MILLISECONDS_IN_A_DAY
 }
 
 val daysAgo = differenceInDays(origin, this)
 return when {
 daysAgo < 0 -> "In the future"
 daysAgo < 1 -> "Today"
 daysAgo < 7 -> "Less than a week ago"
 daysAgo < 30 -> "Less than a month ago"
 daysAgo < 365 -> "Less than a year ago"
 else -> "Long time ago"
 }
 }
  • 27. #AdvArchMobile But ★ A class cannot implement an interface using extensions ★ Methods are declared independently
  • 29. #AdvArchMobile Observation data class ProductRequest(var name: String, var units: Int) class Presenter() { var request: ProductRequest by Delegates.observable(ProductRequest(name="", units=0)) { prop, old, new -> requestChanged() } fun requestChanged() { print("Request: $request”) } fun changeDoesNotTrigger() { request.name = "Something" request.units = 1 } fun completeChangeThatTriggers() { request = ProductRequest(name="Else", units= 2) } }
  • 30. #AdvArchMobile Delegating Reference Type class WeakReferenceHolder<T, U> {
 private var propertyRef: WeakReference<U>? = null
 
 operator fun getValue(t: T, property: KProperty<*>): U? = propertyRef?.get()
 
 operator fun setValue(t: T, property: KProperty<*>, newValue: U?) {
 propertyRef = if (newValue != null) {
 WeakReference(newValue)
 } else {
 null
 }
 }
 }
 var view: ProgrammersListView? by WeakReferenceHolder<ProgrammersListPresenter, ProgrammersListView>()
  • 33. #AdvArchMobile Avoid Enums ★ Space ★ Performance Sealed Classes Too!
  • 34. #AdvArchMobile Don’t* sealed class Interactor { class ShowProducts(val completion: ()- >Unit): Interactor() {} class DeleteProduct(id: String, completion: ()->Unit) {} } when (interactor) { is ShowProducts -> … }
  • 35. #AdvArchMobile Do sealed class Result<V: Any, E: Exception> { class Success<V: Any, E: Exception>(val value: V) : Result<V, E>() {//…} class Failure<V: Any, E: Exception>(val error: E) : Result<V, E>() {//…} }
  • 36. Recap
  • 37. #AdvArchMobile Recap ★ Kotlin makes advanced architectures easier ★ Learn your options and choose ★ Still learning the idioms, work with the community