Advanced #6 clean architecture
- 4. We want to be able to
REACT TO CHANGES
quickly & efficiently
- 6. Keep in mind
•Architecture is dynamic and ever-evolving
•There are always several solutions to every problem
•Every architecture decision is a trade-off
•There is no such thing as “the perfect
architecture”
- 10. Movie Night app layers
Presentation
Data
Domain
•UI
•Presenters
•Dependency Injection
•Web API
•Storage (DB/In-Mem)
•Use cases
•Interfaces
•Domain Entities
DependenciesFlow
- 13. Movie Night app layers
Presentation
Data
Domain
•UI
•Presenters
•Dependency Injection
•Web API
•Storage (DB/In-Mem)
•Use cases
•Interfaces
•Domain Entities
DependenciesFlow
- 14. The Domain Layer
•The baseline of the application
•Describes what the application is / what it can do
•Generic code
- 16. Domain Entities
• Simple data containers
• The basic building blocks of our application
• Acts as common language across the
application
- 38. Interfaces
• Dictates the contract the upper layers must
follow
• Ensures the application core functionality will
hold true, regardless implementation details
changes
- 41. Movie Night app layers
Data
Domain
•Web API
•Storage (DB/In-Mem)
•Domain Entities
•Interfaces
•Use cases
- 48. MyMapper.kt
class MyMapper: Mapper<MovieEntity, MovieData>() {
override fun mapFrom(from: MovieEntity): MovieData {
return MovieData(
id = from.id,
originalTitle = from.originalTitle,
releaseDate = from.releaseDate,
overview = from.overview
// ...
)
}
}
- 49. MyMapper.kt
class MyMapper: Mapper<MovieEntity, MovieData>() {
override fun mapFrom(from: MovieEntity): MovieData {
return MovieData(
id = from.id,
originalTitle = from.originalTitle,
releaseDate = from.releaseDate,
overview = from.overview
// ...
)
}
}
- 50. MyMapper.kt
class MyMapper: Mapper<MovieEntity, MovieData>() {
override fun mapFrom(from: MovieEntity): MovieData {
return MovieData(
id = from.id,
originalTitle = from.originalTitle,
releaseDate = from.releaseDate,
overview = from.overview
// ...
)
}
}
- 53. Why do we need Mappers?
The Data layer contains details
we want to hide.
- 60. Movie Night app layers
Presentation
Data
Domain
•UI
•Presenters
•Dependency Injection
•Web API
•Storage (DB/In-Mem)
•Use cases
•Interfaces
•Domain Entities
DependenciesFlow
- 72. LiveData 101
// Creating
val liveData = MutableLiveData<String>()
// Observing
liveData.observe(lifecycleOwner, Observer { data ->
// do something with data…
})
// Updating value
liveData.value = "Hello world!"
- 73. LiveData 101
// Creating
val liveData = MutableLiveData<String>()
// Observing
liveData.observe(lifecycleOwner, Observer { data ->
// do something with data…
})
// Updating value
liveData.value = "Hello world!"
- 74. LiveData 101
// Creating
val liveData = MutableLiveData<String>()
// Observing
liveData.observe(lifecycleOwner, Observer { data ->
// do something with data…
})
// Updating value
liveData.value = "Hello world!"
- 83. class PopularViewModel(val useCase: GetPopularMovies)
: BaseViewModel() {
var viewState: MutableLiveData<PopularViewState>
init {
viewState.value = PopularViewState()
}
PopularViewModel.kt
- 84. class PopularViewModel(val useCase: GetPopularMovies)
: BaseViewModel() {
var viewState: MutableLiveData<PopularViewState>
init {
viewState.value = PopularViewState()
}
PopularViewModel.kt
- 85. class PopularViewModel(val useCase: GetPopularMovies)
: BaseViewModel() {
var viewState: MutableLiveData<PopularViewState>
init {
// Sets the initial view state
viewState.value = PopularViewState()
}
// ...
PopularViewModel.kt
- 93. PopularMoviesFragment.kt
val viewModel = ViewModelProviders
.of(this, factory)
.get(PopularViewModel::class.java)
// ...
viewModel.viewState
.observe(this, Observer { state ->
handleViewState(state)
})
- 94. PopularMoviesFragment.kt
val viewModel = ViewModelProviders
.of(this, factory)
.get(PopularViewModel::class.java)
// ...
viewModel.viewState
.observe(this, Observer { state ->
handleViewState(state)
})