SlideShare uma empresa Scribd logo
1 de 87
Baixar para ler offline
Session 2 l Rainist
Efficient and Testable MVVM pattern
Session 2. Android archietecture
@omjoonkim
with using AAC, Rx, Koin
Android .
?
MVC
MVP
MVVM
MVI
VIPER
etc…
MVC
MVP
MVVM
MVI
VIPER
etc…
MVC
MVP
MVVM
MVI
VIPER
etc…
with CleanArchitecture
with RFP(rxJava2)
with AAC, Koin
with Spek
MVVM?
why MVVM?
?
Presenter code 1000Line 😨
😓
( ) 🤕
View Presenter 🤒
☝
Business Logic ☝
☝
☝
👇
👇
what MVVM?
MVVM….
- Model View ViewModel
- ViewModel View .
- View ViewModel n:m .
- View ViewModel bindable .
Model View ViewModel
VIEW
VIEW
MODEL
MODEL
DataBinding
Notification
Update
Notification
ViewModel View .
- ViewModel View .
- ViewModel View input output .
- input output .
- (input) (output) .
- .
- output View Route .
View ViewModel n:m .
- View ViewModel .
- ViewModel View .
- .
VIEW
VIEW
MODEL
MODEL
DataBinding
View ViewModel bindable .
Notification Notification
Update
View ViewModel bindable .
- View ViewModel .
- (View -> ViewModel)
- View (ViewModel -> View)
- PS. binding .
…
VIEW
VIEW
MODEL
MODEL
DataBinding
Databinding,
LiveData
RxJava
View 

ViewModel
.
binding input output
.
Databinding
.
How MVVM?
Efficiently
Testable
on Android? 🤔
VIEW
VIEW
MODEL
MODEL
DataBinding
Notification
Update
Notification
on Android! 🙌
VIEW
VIEW
MODEL
MODEL
DataBinding
LiveData
UseCase
Rx
VIEW
VIEW
MODEL
MODEL
DataBinding
LiveData
UseCase
Rx
XML
(databindingUtil)
Activity
or Fragment
or something
on Android! 🙌
VIEW
VIEW
MODEL
MODEL
DataBinding
LiveData
UseCase
Rx
XML
(databindingUtil)
Activity
or Fragment
or something
View
Router + ViewModel View binding
.
on Android! 🙌
✨
- CleanArchitecture
- Koin IOC(Inversion Of Control)
- Spek .
…
https://github.com/omjoonkim/GitHubBrowserApp
✨
package
package
App
Data
Domain
Remote
CleanArchitecture
UI
Data
Domain
Remote
Presentation
Koin!
Koin?
- Library.(DI x)
- Kotlin .
- !
- AAC ✨
- Service Locator .
- Runtime .
Koin!
val myModule: Module = module {
viewModel { (id: String) -> MainViewModel(id, get(), get()) }
viewModel { SearchViewModel(get()) }
//app
single { Logger() }
single { AppSchedulerProvider() as SchedulersProvider }
//domain
single { GetUserData(get(), get()) }
//data
single { GithubBrowserDataSource(get()) as GitHubBrowserRepository }
//remote
single { GithubBrowserRemoteImpl(get(), get(), get()) as GithubBrowserRemote }
single { RepoEntityMapper() }
single { UserEntityMapper() }
single {
GithubBrowserServiceFactory.makeGithubBrowserService(
BuildConfig.DEBUG,
"https://api.github.com"
)
}
}
Koin!
class App : Application() {
override fun onCreate() {
super.onCreate()
startKoin(
this,
listOf(myModule)
)
}
}
SearchActivity
SearchView - Input?
name
clickSearchButton
SearchView - Output?
STATE
enableSearchButton
Route
goResultActivity
SearchViewModel - constructor
class SearchViewModel(
logger: Logger
) : BaseViewModel()
BaseViewModel
abstract class BaseViewModel : ViewModel(){
protected val compositeDisposable : CompositeDisposable = CompositeDisposable()
override fun onCleared() {
super.onCleared()
compositeDisposable.clear()
}
}
SearchViewModel - input, output, state
interface SearchViewModelInPuts : Input {
fun name(name: String)
fun clickSearchButton()
}
interface SearchViewModelOutPuts : Output {
fun state(): LiveData<SearchViewState>
fun goResultActivity(): LiveData<String>
}
data class SearchViewState(
val enableSearchButton: Boolean
)
SearchViewModel - properties
private val name = PublishSubject.create<String>()
private val clickSearchButton = PublishSubject.create<Parameter>()
val input = object : SearchViewModelInPuts {
override fun name(name: String) =
this@SearchViewModel.name.onNext(name)
override fun clickSearchButton() =
this@SearchViewModel.clickSearchButton.onNext(Parameter.CLICK)
}
private val state = MutableLiveData<SearchViewState>()
private val goResultActivity = MutableLiveData<String>()
val output = object : SearchViewModelOutPuts {
override fun state() = state
override fun goResultActivity() = goResultActivity
}
SearchViewModel - logic
init {
compositeDisposable.addAll(
name.map { SearchViewState(it.isNotEmpty()) }
.subscribe(state::setValue, logger::d),
name.takeWhen(clickSearchButton) { _, t2 -> t2 }
.subscribe(goResultActivity::setValue, logger::d)
)
}
SearchViewModel - logic
init {
compositeDisposable.addAll(
name.map { SearchViewState(it.isNotEmpty()) }
.subscribe(state::setValue, logger::d),
name.takeWhen(clickSearchButton) { _, t2 -> t2 }
.subscribe(goResultActivity::setValue, logger::d)
)
}
SearchView
<data>
<import type="android.view.View"/>
<variable
name="viewModel"
type="com.omjoonkim.app.githubBrowserApp.viewmodel.SearchViewModel"
/>
</data>
SearchView - Databinding
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="48dp"
android:onTextChanged='@{(s,start,end,before) -> viewModel.input.name(s.toString ?? "")}'
/>
<Button
android:id="@+id/button_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="@{viewModel.output.state().enableSearchButton}"
android:onClick="@{(v) -> viewModel.input.clickSearchButton()}"
android:text="search"
/>
SearchView - Databinding
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="48dp"
android:onTextChanged='@{(s,start,end,before) -> viewModel.input.name(s.toString ?? "")}'
/>
<Button
android:id="@+id/button_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="@{viewModel.output.state().enableSearchButton}"
android:onClick="@{(v) -> viewModel.input.clickSearchButton()}"
android:text="search"
/>
SearchActivity
class SearchActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivitySearchBinding>(this,…)
binding.setLifecycleOwner(this)
val viewModel = getViewModel<SearchViewModel>()
binding.viewModel = viewModel
viewModel.output.goResultActivity()
.observe {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("githubbrowser://repos/$it")
)
)
}
}
}
SearchActivity - state binding
class SearchActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivitySearchBinding>(this,…)
binding.setLifecycleOwner(this)
val viewModel = getViewModel<SearchViewModel>()
binding.viewModel = viewModel
viewModel.output.goResultActivity()
.observe {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("githubbrowser://repos/$it")
)
)
}
}
}
SearchActivity - router binding
class SearchActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivitySearchBinding>(this,…)
binding.setLifecycleOwner(this)
val viewModel = getViewModel<SearchViewModel>()
binding.viewModel = viewModel
viewModel.output.goResultActivity()
.observe {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("githubbrowser://repos/$it")
)
)
}
}
}
ResultActivity
ResultView - Input?
clickHomeButton
clickUser
ResultView - Output?
STATE
title
showLoading
ROUTER
refreshListData
finish
showErrorToast
goProfileActivity
MainViewModel - constructor
class MainViewModel(
searchedUserName: String,
private val getUserData: GetUserData,
logger: Logger
) : BaseViewModel()
MainViewModel - input, output, state
interface MainViewModelInputs : Input {
fun clickUser(user: User)
fun clickHomeButton()
}
interface MainViewModelOutPuts : Output {
fun state(): LiveData<MainViewState>
fun refreshListData(): LiveData<Pair<User, List<Repo>>>
fun showErrorToast(): LiveData<String>
fun goProfileActivity(): LiveData<String>
fun finish(): LiveData<Unit>
}
data class MainViewState(
val showLoading: Boolean,
val title: String
)
MainViewModel - properties
private val clickUser = PublishSubject.create<User>()
private val clickHomeButton = PublishSubject.create<Parameter>()
val input: MainViewModelInputs = object : MainViewModelInputs {
override fun clickUser(user: User) = clickUser.onNext(user)
override fun clickHomeButton() = clickHomeButton.onNext(Parameter.CLICK)
}
private val state = MutableLiveData<MainViewState>()
private val refreshListData = MutableLiveData<Pair<User, List<Repo>>>()
private val showErrorToast = MutableLiveData<String>()
private val goProfileActivity = MutableLiveData<String>()
private val finish = MutableLiveData<Unit>()
val output = object : MainViewModelOutPuts {
override fun state() = state
override fun refreshListData() = refreshListData
override fun showErrorToast() = showErrorToast
override fun goProfileActivity() = goProfileActivity
override fun finish() = finish
}
MainViewModel - logic
init {
val error = PublishSubject.create<Throwable>()
val userName = Observable.just(searchedUserName).share()
val requestListData = userName.flatMapMaybe {
getUserData.get(it).neverError(error)
}.share()
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
val error = PublishSubject.create<Throwable>()
val userName = Observable.just(searchedUserName).share()
val requestListData = userName.flatMapMaybe {
getUserData.get(it).neverError(error)
}.share()
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainViewModel - logic
compositeDisposable.addAll(
Observables
.combineLatest(
Observable.merge(
requestListData.map { false },
error.map { false }
).startWith(true),
userName,
::MainViewState
).subscribe(state::setValue, logger::d),
requestListData.subscribe(refreshListData::setValue, logger::d),
error.map {
if (it is Error)
it.errorText
else UnExpected.errorText
}.subscribe(showErrorToast::setValue, logger::d),
clickUser.map { it.name }.subscribe(goProfileActivity::setValue, logger::d),
clickHomeButton.subscribe(finish::call, logger::d)
)
MainView
<data>
<import type="android.view.View"/>
<variable
name="viewModel"
type="com.omjoonkim.app.githubBrowserApp.viewmodel.MainViewModel"
/>
</data>
MainView - Databinding
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@{viewModel.output.state().title}"
/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="@{viewModel.output.state().showLoading ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appBar"
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</FrameLayout>
MainView - Databinding
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@{viewModel.output.state().title}"
/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="@{viewModel.output.state().showLoading ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appBar"
>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</FrameLayout>
MainActivity
val binding = DataBindingUtil.setConten…..
binding.setLifecycleOwner(this)
val viewModel = getViewModel<MainViewModel> {
parametersOf(intent.data.path.substring(1))
}
binding.viewModel = viewModel
actionbarInit(binding.toolbar, onClickHomeButton = {
viewModel.input.clickHomeButton()
})
MainActivity
with(viewModel.output) {
refreshListData().observe { (user, repos) ->
binding.recyclerView.adapter = MainListAdapter(
user,
repos,
viewModel.input::clickUser
)
}
showErrorToast().observe { showToast(it) }
goProfileActivity().observe {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("githubbrowser://repos/$it")
)
)
}
finish().observe {
onBackPressed()
}
}
Test
HOW? 😎
-
- Test SchedulersProvider .
- Test DummyApiService .
- Spek + LiveData .
- Spek
- Feature
- Scenario
- Given
- When
- Then
TestSchedulerProvider
class TestSchedulerProvider : SchedulersProvider {
override fun io() = Schedulers.trampoline()
override fun ui() = Schedulers.trampoline()
}
TestDummyGithubBrowserService
class TestDummyGithubBrowserService : GithubBrowserService {
override fun getUserInfo(userName: String): Single<UserModel> =
Single.just(
UserModel("omjoonkim", "")
)
override fun getUserRepos(userName: String): Single<List<RepoModel>> =
Single.just(
listOf(
RepoModel("repo1", "repo1 description", "1"),
RepoModel("repo2", "repo2 description", "2"),
RepoModel("repo3", "repo3 description", "3")
)
)
}
DI for Test
val testModule = module {
single(override = true) {
TestSchedulerProvider() as SchedulersProvider
}
single(override = true) {
TestDummyGithubBrowserService() as GithubBrowserService
}
}
val test_module = listOf(myModule, testModule)
for Spek + LiveData
beforeEachTest {
ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
override fun executeOnDiskIO(runnable: Runnable) {
runnable.run()
}
override fun isMainThread(): Boolean {
return true
}
override fun postToMainThread(runnable: Runnable) {
runnable.run()
}
})
}
afterEachTest {
ArchTaskExecutor.getInstance().setDelegate(null)
}
MainViewModelSpec
object MainViewModelSpec : KoinSpek({
beforeEachTest {…}
afterEachTest {…}
lateinit var userName: String
val viewModel: MainViewModel by inject { parametersOf(userName) }
val getUserData: GetUserData by inject()
Feature("MainViewModel spec") {…}
})
Scenario1
Scenario(" , ") {
Given(" omjoonkim "){
userName = "omjoonkim"
}
Then(" ") {
assertEquals(
getUserData.get(userName).blockingGet(),
viewModel.output.refreshListData().value
)
}
}
Scenario2
Scenario(" ") {
When(" ") {
viewModel.input.clickUser(
viewModel.output.refreshListData().value?.first
?: throw IllegalStateException()
)
}
Then(" ") {
assertEquals(
viewModel.output.refreshListData().value?.first?.name
?: throw IllegalStateException(),
viewModel.output.goProfileActivity().value
)
}
}
Scenario3
Scenario(" .") {
When(" ") {
viewModel.input.clickHomeButton()
}
Then(" .") {
assertEquals(
Unit,
viewModel.output.finish().value
)
}
}
✨✨✨
More……. + TMI
Dagger2 vs Koin
- Heavy vs light
- Dependency Injection vs ServiceLocator
- CompileTime vs RunTime
https://twitter.com/jakewharton/status/908419644742098944
Spek Koin
- Spek + Koin .
- Spek Koin
https://github.com/InsertKoinIO/koin/pull/107
+
- Datbinding kotlin 100% .
- xml .
- Router
- Presentation module
Thank you✨✨ by @omjoonkim

Mais conteúdo relacionado

Mais procurados

Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data BindingRadek Piekarz
 
Swift in SwiftUI
Swift in SwiftUISwift in SwiftUI
Swift in SwiftUIBongwon Lee
 
The virtual DOM and how react uses it internally
The virtual DOM and how react uses it internallyThe virtual DOM and how react uses it internally
The virtual DOM and how react uses it internallyClóvis Neto
 
Concevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootConcevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootDNG Consulting
 
Clean architecture: Android
Clean architecture: AndroidClean architecture: Android
Clean architecture: Androidintive
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemeStéphane Traumat
 
iOS architecture patterns
iOS architecture patternsiOS architecture patterns
iOS architecture patternsallanh0526
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesecosio GmbH
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring bootAntoine Rey
 
Web Services - Architecture and SOAP (part 1)
Web Services - Architecture and SOAP (part 1)Web Services - Architecture and SOAP (part 1)
Web Services - Architecture and SOAP (part 1)Martin Necasky
 
Introduction to React
Introduction to ReactIntroduction to React
Introduction to ReactRob Quick
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJSAll Things Open
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications JavaAntoine Rey
 

Mais procurados (20)

Deep dive into Android Data Binding
Deep dive into Android Data BindingDeep dive into Android Data Binding
Deep dive into Android Data Binding
 
Swift in SwiftUI
Swift in SwiftUISwift in SwiftUI
Swift in SwiftUI
 
Spring Web MVC
Spring Web MVCSpring Web MVC
Spring Web MVC
 
The virtual DOM and how react uses it internally
The virtual DOM and how react uses it internallyThe virtual DOM and how react uses it internally
The virtual DOM and how react uses it internally
 
React - Introdução
React - IntroduçãoReact - Introdução
React - Introdução
 
Concevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring BootConcevoir, développer et sécuriser des micro-services avec Spring Boot
Concevoir, développer et sécuriser des micro-services avec Spring Boot
 
REST API with CakePHP
REST API with CakePHPREST API with CakePHP
REST API with CakePHP
 
Clean architecture: Android
Clean architecture: AndroidClean architecture: Android
Clean architecture: Android
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosysteme
 
iOS architecture patterns
iOS architecture patternsiOS architecture patterns
iOS architecture patterns
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examples
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring boot
 
Web Services - Architecture and SOAP (part 1)
Web Services - Architecture and SOAP (part 1)Web Services - Architecture and SOAP (part 1)
Web Services - Architecture and SOAP (part 1)
 
Introduction to React
Introduction to ReactIntroduction to React
Introduction to React
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
 
Vue js for beginner
Vue js for beginner Vue js for beginner
Vue js for beginner
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 

Semelhante a [22]Efficient and Testable MVVM pattern

Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Natasha Murashev
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019UA Mobile
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Patterngoodfriday
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesRiad Benguella
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsScott Gardner
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupNatasha Murashev
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Eyal Vardi
 
Android Jetpack: ViewModel and Testing
Android Jetpack: ViewModel and TestingAndroid Jetpack: ViewModel and Testing
Android Jetpack: ViewModel and TestingYongjun Kim
 
Functional Reactive Programming - RxSwift
Functional Reactive Programming - RxSwiftFunctional Reactive Programming - RxSwift
Functional Reactive Programming - RxSwiftRodrigo Leite
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014Fábio Pimentel
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databindingBoulos Dib
 
Functionnal view modelling
Functionnal view modelling Functionnal view modelling
Functionnal view modelling Hugo Saynac
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Coe-Legion
 
MVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin WayMVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin WayZeyad Gasser
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Mahmoud Hamed Mahmoud
 
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...Stanfy
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementationaurelianaur
 

Semelhante a [22]Efficient and Testable MVVM pattern (20)

Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)Protocol-Oriented MVVM (extended edition)
Protocol-Oriented MVVM (extended edition)
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
 
Protocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS MeetupProtocol Oriented MVVM - Auckland iOS Meetup
Protocol Oriented MVVM - Auckland iOS Meetup
 
Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)Angular 2 Architecture (Bucharest 26/10/2016)
Angular 2 Architecture (Bucharest 26/10/2016)
 
Android Jetpack: ViewModel and Testing
Android Jetpack: ViewModel and TestingAndroid Jetpack: ViewModel and Testing
Android Jetpack: ViewModel and Testing
 
Functional Reactive Programming - RxSwift
Functional Reactive Programming - RxSwiftFunctional Reactive Programming - RxSwift
Functional Reactive Programming - RxSwift
 
Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014
Conceitos e prática no desenvolvimento iOS - Mobile Conf 2014
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databinding
 
Functionnal view modelling
Functionnal view modelling Functionnal view modelling
Functionnal view modelling
 
MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Co
 
MVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin WayMVI - Managing State The Kotlin Way
MVI - Managing State The Kotlin Way
 
Android development
Android developmentAndroid development
Android development
 
Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development Windows Store app using XAML and C#: Enterprise Product Development
Windows Store app using XAML and C#: Enterprise Product Development
 
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
Stanfy MadCode Meetup #11: Why do you need to switch from Obj-C to Swift, or ...
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementation
 

Mais de NAVER Engineering

디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIXNAVER Engineering
 
진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)NAVER Engineering
 
서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트NAVER Engineering
 
BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호NAVER Engineering
 
이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라NAVER Engineering
 
날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기NAVER Engineering
 
쏘카프레임 구축 배경과 과정
 쏘카프레임 구축 배경과 과정 쏘카프레임 구축 배경과 과정
쏘카프레임 구축 배경과 과정NAVER Engineering
 
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기NAVER Engineering
 
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)NAVER Engineering
 
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드NAVER Engineering
 
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기NAVER Engineering
 
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활NAVER Engineering
 
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출NAVER Engineering
 
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우NAVER Engineering
 
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...NAVER Engineering
 
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법NAVER Engineering
 
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며NAVER Engineering
 
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기NAVER Engineering
 
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기NAVER Engineering
 

Mais de NAVER Engineering (20)

React vac pattern
React vac patternReact vac pattern
React vac pattern
 
디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX디자인 시스템에 직방 ZUIX
디자인 시스템에 직방 ZUIX
 
진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)진화하는 디자인 시스템(걸음마 편)
진화하는 디자인 시스템(걸음마 편)
 
서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트서비스 운영을 위한 디자인시스템 프로젝트
서비스 운영을 위한 디자인시스템 프로젝트
 
BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호BPL(Banksalad Product Language) 무야호
BPL(Banksalad Product Language) 무야호
 
이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라이번 생에 디자인 시스템은 처음이라
이번 생에 디자인 시스템은 처음이라
 
날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기날고 있는 여러 비행기 넘나 들며 정비하기
날고 있는 여러 비행기 넘나 들며 정비하기
 
쏘카프레임 구축 배경과 과정
 쏘카프레임 구축 배경과 과정 쏘카프레임 구축 배경과 과정
쏘카프레임 구축 배경과 과정
 
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
플랫폼 디자이너 없이 디자인 시스템을 구축하는 프로덕트 디자이너의 우당탕탕 고통 연대기
 
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
200820 NAVER TECH CONCERT 15_Code Review is Horse(코드리뷰는 말이야)(feat.Latte)
 
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
200819 NAVER TECH CONCERT 03_화려한 코루틴이 내 앱을 감싸네! 코루틴으로 작성해보는 깔끔한 비동기 코드
 
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
200819 NAVER TECH CONCERT 10_맥북에서도 아이맥프로에서 빌드하는 것처럼 빌드 속도 빠르게 하기
 
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
200819 NAVER TECH CONCERT 08_성능을 고민하는 슬기로운 개발자 생활
 
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
200819 NAVER TECH CONCERT 05_모르면 손해보는 Android 디버깅/분석 꿀팁 대방출
 
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
200819 NAVER TECH CONCERT 09_Case.xcodeproj - 좋은 동료로 거듭나기 위한 노하우
 
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
200820 NAVER TECH CONCERT 14_야 너두 할 수 있어. 비전공자, COBOL 개발자를 거쳐 네이버에서 FE 개발하게 된...
 
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
200820 NAVER TECH CONCERT 13_네이버에서 오픈 소스 개발을 통해 성장하는 방법
 
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
200820 NAVER TECH CONCERT 12_상반기 네이버 인턴을 돌아보며
 
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
200820 NAVER TECH CONCERT 11_빠르게 성장하는 슈퍼루키로 거듭나기
 
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
200819 NAVER TECH CONCERT 07_신입 iOS 개발자 개발업무 적응기
 

Último

Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 

Último (20)

Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

[22]Efficient and Testable MVVM pattern