Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

Home Improvement: Architecture & Kotlin Slide 1 Home Improvement: Architecture & Kotlin Slide 2 Home Improvement: Architecture & Kotlin Slide 3 Home Improvement: Architecture & Kotlin Slide 4 Home Improvement: Architecture & Kotlin Slide 5 Home Improvement: Architecture & Kotlin Slide 6 Home Improvement: Architecture & Kotlin Slide 7 Home Improvement: Architecture & Kotlin Slide 8 Home Improvement: Architecture & Kotlin Slide 9 Home Improvement: Architecture & Kotlin Slide 10 Home Improvement: Architecture & Kotlin Slide 11 Home Improvement: Architecture & Kotlin Slide 12 Home Improvement: Architecture & Kotlin Slide 13 Home Improvement: Architecture & Kotlin Slide 14 Home Improvement: Architecture & Kotlin Slide 15 Home Improvement: Architecture & Kotlin Slide 16 Home Improvement: Architecture & Kotlin Slide 17 Home Improvement: Architecture & Kotlin Slide 18 Home Improvement: Architecture & Kotlin Slide 19 Home Improvement: Architecture & Kotlin Slide 20 Home Improvement: Architecture & Kotlin Slide 21 Home Improvement: Architecture & Kotlin Slide 22 Home Improvement: Architecture & Kotlin Slide 23 Home Improvement: Architecture & Kotlin Slide 24 Home Improvement: Architecture & Kotlin Slide 25 Home Improvement: Architecture & Kotlin Slide 26 Home Improvement: Architecture & Kotlin Slide 27 Home Improvement: Architecture & Kotlin Slide 28 Home Improvement: Architecture & Kotlin Slide 29 Home Improvement: Architecture & Kotlin Slide 30 Home Improvement: Architecture & Kotlin Slide 31 Home Improvement: Architecture & Kotlin Slide 32 Home Improvement: Architecture & Kotlin Slide 33 Home Improvement: Architecture & Kotlin Slide 34 Home Improvement: Architecture & Kotlin Slide 35 Home Improvement: Architecture & Kotlin Slide 36 Home Improvement: Architecture & Kotlin Slide 37 Home Improvement: Architecture & Kotlin Slide 38 Home Improvement: Architecture & Kotlin Slide 39
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

0 Likes

Share

Download to read offline

Home Improvement: Architecture & Kotlin

Download to read offline

Two of the most relevant news from the recent Google IO were the Guide to App Architecture and the adoption of Kotlin as a first-class language. Both have a very positive impact in our applications.

In my talk I introduced and advanced architecture inspired in the Clean Architecture of Uncle Bob and I showed the impact of these two elements.

First I mentioned the components provided for integration with the lifecycle and how that saves a lot of effort to preserve view models or presenters. I briefly covered the methods that we had available until know focusing on the use of a fragment with no view that had the retained instance property set to true.

Then I covered some real scenarios explaining the improvements that Kotlin provide us with. Some examples:
- Conciseness of data classes (and limitations)
- Property observation
- Use of extensions in presentation logic
- Sealed classes for results (as an either-like type)

This is a "Code or it didn't happen" (TM) talk. ;-)

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Home Improvement: Architecture & Kotlin

  1. 1. Home Improvement: Architecture & Kotlin Jorge D. Ortiz-Fuentes @jdortiz
  2. 2. #AdvArchMobile A Canonical Examples Production
  3. 3. #AdvArchMobile Disclaimer
  4. 4. #AdvArchMobile Agenda ★ Architecture ★ Kotlin ★ Recap
  5. 5. Clean Architecture
  6. 6. Persistance FW View Network LocationFW Presenter Entity Gateway Clean Architecture Interactor Entity
  7. 7. Dependency Inversion Principle High Level Low LevelAbstraction Low Level
  8. 8. #AdvArchMobile Respectful Criticism about some Opinionated Decisions
  9. 9. #AdvArchMobile Architecture Components ★ Awesome starting point ★ View Models (inner layer) depend on the SDK:AndroidViewModel (outer layer)
  10. 10. Kotlin
  11. 11. #AdvArchMobile Kotlin ★ Conciseness ★ Data Classes ★ Extensions ★ Property Delegation ★ Sealed Classes
  12. 12. Conciseness
  13. 13. #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);
 }
 }
  14. 14. #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);
 }
 }
  15. 15. #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)
  16. 16. #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());
 }
  17. 17. #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());
 }
  18. 18. #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
  19. 19. Data Classes
  20. 20. #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"
 }
  21. 21. #AdvArchMobile But ★ Not a value type ★ No defensive copy
  22. 22. #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) } }
  23. 23. Extensions
  24. 24. #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"
 }
 }
  25. 25. #AdvArchMobile But ★ A class cannot implement an interface using extensions ★ Methods are declared independently
  26. 26. Property Delegation
  27. 27. #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) } }
  28. 28. #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>()
  29. 29. Sealed Classes
  30. 30. Enum considered harmful
  31. 31. #AdvArchMobile Avoid Enums ★ Space ★ Performance Sealed Classes Too!
  32. 32. #AdvArchMobile Don’t* sealed class Interactor { class ShowProducts(val completion: ()- >Unit): Interactor() {} class DeleteProduct(id: String, completion: ()->Unit) {} } when (interactor) { is ShowProducts -> … }
  33. 33. #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>() {//…} }
  34. 34. Recap
  35. 35. #AdvArchMobile Recap ★ Kotlin makes advanced architectures easier ★ Learn your options and choose ★ Still learning the idioms, work with the community
  36. 36. Thank You!
  37. 37. @jdortiz #AdvArchMobile

Two of the most relevant news from the recent Google IO were the Guide to App Architecture and the adoption of Kotlin as a first-class language. Both have a very positive impact in our applications. In my talk I introduced and advanced architecture inspired in the Clean Architecture of Uncle Bob and I showed the impact of these two elements. First I mentioned the components provided for integration with the lifecycle and how that saves a lot of effort to preserve view models or presenters. I briefly covered the methods that we had available until know focusing on the use of a fragment with no view that had the retained instance property set to true. Then I covered some real scenarios explaining the improvements that Kotlin provide us with. Some examples: - Conciseness of data classes (and limitations) - Property observation - Use of extensions in presentation logic - Sealed classes for results (as an either-like type) This is a "Code or it didn't happen" (TM) talk. ;-)

Views

Total views

379

On Slideshare

0

From embeds

0

Number of embeds

4

Actions

Downloads

1

Shares

0

Comments

0

Likes

0

×