SlideShare a Scribd company logo
1 of 66
Download to read offline
RIBs
Fragments which work
Dmitry Zaytsev, Android Engineer @ Uber
1
Why Fragments?
2
3
MainActivity
4
RIBs - Fragments which work
● Encapsulation
● Lifecycle
● Navigation
Why Fragments
Fragments are great!
7
Why not Fragments?
8
● Encapsulation
● Lifecycle
● Navigation
● Scalability
Why not Fragments
10
Listeners
No compile-time safety
A dynamic type check needs to be
performed at runtime which could (and will)
lead to crashes.
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is Listener) {
listener = context
} else if (parentFragment is Listener) {
listener = parentFragment as Listener
} else {
throw RuntimeException()
}
}
Back Stack
12
FragmentA FragmentB FragmentC
Back Stack
Simple yet hard to use
Back stack works well when you don’t need
to handle back navigation yourself or use
children fragments. However, as soon as you
need to do any customization it quickly falls
apart.
// Attach Root fragment
supportFragmentManager.beginTransaction()
.apply {
add(R.id.fragmentContainer, RootFragment.newInstance(), "Root")
addToBackStack(null)
}
.commit()
// Attach Child fragment
rootFragment.childFragmentManager.beginTransaction()
.apply {
add(R.id.rootContainer, ChildFragment.newInstance(), null)
addToBackStack(null)
}
.commit()
// Press back
MainActivity
MainFragment
14
● Too many lifecycle states
● No compile-time safety when calling listeners
● Nested fragments is an afterthought
● Passing arguments
● Testability
● Non-restrictive API
● Fragments are an Android thing
● Requires glue code
Problems
16
500+Mobile Engineers who
worked on new Uber app
200+ Android Engineers who
made at least 1 commint
in Android monorepo
500+iOS Engineers who made
at least 1 commit in iOS
monorepo
Some Numbers
17
RIBs - Fragments which work
Account Info
Account Info
Balance Pill
Account Info
Balance Pill
Map
Account Info
Balance Pill
Safety Info
Map
Account Info
Balance Pill
Safety Info
Status
Map
M - V - Something
24
Naive MVP
25
Model Presenter View
Update
Read
Notify
Populate
● Works well for individual pieces
● Countless variations of the pattern
● Requires glue code
● Development slows down
● Integration points are main source of bugs
Naive MVP / MVVM
RIBs
27
Router
Interactor
Builder
28
Router
Interactor
Builder
29
Router
Interactor
Builder
30
Naive MVP
31
Model Presenter View
Update
Read
Notify
Populate
RIB
32
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
RIB
33
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
Router
Navigate
RIB
34
Interactor Presenter View
Notify
Present
Notify
Populate
Model
Update
Read
Router
Navigate
Builder
Build
Example
35
ProductList
ProductDetails
Interactor
Simple Lifecycle
Just 2 lifecycle events. Sometimes even less
than that. @Override
protected void didBecomeActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
// Subscribe to data source. Ready to update UI.
}
@Override
protected void willResignActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
// Tear down and remove subscriptions/callbacks.
}
Interactor
Business Logic
Loads data from Model layer, makes
decisions and asks Presenter to render UI.
Talks to Router to perform navigation.
@Override
protected void didBecomeActive(@Nullable Bundle savedInstanceState) {
super.didBecomeActive(savedInstanceState);
presenter.showLoading();
productApi.getProducts()
.observeOn(AndroidSchedulers.mainThread())
.as(autoDisposable(this))
.subscribe(result -> {
presenter.hideLoading();
if (result.isSuccess()) {
presenter.showProducts(result.getResult());
} else {
presenter.showError();
}
});
}
Router
Navigation
Creates other RIBs and attaches them to
view hierarchy.
void routeToProductDetails(Product product) {
ProductDetailsRouter router = productDetailsBuilder.build(
getView(),
product
);
attachChild(router);
getView().addView(router.getView());
}
Builder
Builds
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
public Router build() {
// Builds and returns a router
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Builder
Configuration
Instantiates Interactor, Router and View.
Provides dependencies. Specifies which
dependencies to request from a parent RIB.
@Override
protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) {
return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false);
}
public interface ParentComponent extends ProductDetailsBuilder.ParentComponent {
ProductNetworkApi productNetworkApi();
}
@dagger.Module
public abstract static class Module {
@BindsInstance
public abstract ProductDetailsInteractor.Listener productDetailsListener(
ProductListInteractor interactor
);
}
@dagger.Component(
modules = RootBuilder.Module.class,
dependencies = ParentComponent.class
)
interface Component extends InteractorBaseComponent<ProductListInteractor>,
ProductDetailsBuilder.ParentComponent {
// Dagger initialization
}
Composition
46
Account Info
Balance Pill
Safety Info
Status
Map
48
Root
Root
Logged InLogged Out
50
Root
Logged InLogged Out
Sign Up Log In
51
Root
Logged InLogged Out
MapSign Up Log In
52
Root
Logged InLogged Out
Map
Balance StatusProfile
Sign Up Log In
53
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
Where is Activity?
54
55
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
RootActivity
Modularization
56
57
Root
Logged InLogged Out
Map
Balance StatusProfile
Payments
Sign Up Log In
+
58
What’s the catch?
59
RIBs - Fragments which work
RIBs - Fragments which work
● Screen rotation
● Transition animations
Not included
Where to grab it?
63
uber/RIBs
64
● Good parts of MVP
● Composable
● Compile-time independent
● OS agnostic
● Scalable
● Single-Activity as a bonus
Summary
Thank you!
Time for questions
Dmitry Zaytsev, dmitry.zaytsev@uber.com
Twitter: @dizaytsev
Medium: @dmitry.zaicew

More Related Content

What's hot

Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservicesseges
 
Java EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsJava EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsHirofumi Iwasaki
 
Spring boot for buidling microservices
Spring boot for buidling microservicesSpring boot for buidling microservices
Spring boot for buidling microservicesNilanjan Roy
 
Spring - CDI Interop
Spring - CDI InteropSpring - CDI Interop
Spring - CDI InteropRay Ploski
 
Head toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMHead toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMYuji Kubota
 
Making React Native UI Components with Swift
Making React Native UI Components with SwiftMaking React Native UI Components with Swift
Making React Native UI Components with SwiftRay Deck
 
Springboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testSpringboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testHyukSun Kwon
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your GraphVMware Tanzu
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejugrobbiev
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Arun Gupta
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafMasatoshi Tada
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Stacy Devino
 
Krazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazy Koder
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopPeter Lehto
 
The Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeThe Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeVMware Tanzu
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentationguest11106b
 

What's hot (20)

Spring Boot and Microservices
Spring Boot and MicroservicesSpring Boot and Microservices
Spring Boot and Microservices
 
Java EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise SystemsJava EE 7 for Real Enterprise Systems
Java EE 7 for Real Enterprise Systems
 
Spring boot for buidling microservices
Spring boot for buidling microservicesSpring boot for buidling microservices
Spring boot for buidling microservices
 
Spring - CDI Interop
Spring - CDI InteropSpring - CDI Interop
Spring - CDI Interop
 
Head toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DMHead toward Java 14 and Java 15 #LINE_DM
Head toward Java 14 and Java 15 #LINE_DM
 
Making React Native UI Components with Swift
Making React Native UI Components with SwiftMaking React Native UI Components with Swift
Making React Native UI Components with Swift
 
Springboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testSpringboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with test
 
Spring Up Your Graph
Spring Up Your GraphSpring Up Your Graph
Spring Up Your Graph
 
Enterprise Guice 20090217 Bejug
Enterprise Guice 20090217 BejugEnterprise Guice 20090217 Bejug
Enterprise Guice 20090217 Bejug
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Javaee6 Overview
Javaee6 OverviewJavaee6 Overview
Javaee6 Overview
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
Getting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with ThymeleafGetting start Java EE Action-Based MVC with Thymeleaf
Getting start Java EE Action-Based MVC with Thymeleaf
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!Async task, threads, pools, and executors oh my!
Async task, threads, pools, and executors oh my!
 
Krazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernateKrazykoder struts2 spring_hibernate
Krazykoder struts2 spring_hibernate
 
JavaEE with Vaadin - Workshop
JavaEE with Vaadin - WorkshopJavaEE with Vaadin - Workshop
JavaEE with Vaadin - Workshop
 
The Past Year in Spring for Apache Geode
The Past Year in Spring for Apache GeodeThe Past Year in Spring for Apache Geode
The Past Year in Spring for Apache Geode
 
Hibernate Presentation
Hibernate  PresentationHibernate  Presentation
Hibernate Presentation
 

Similar to RIBs - Fragments which work

Spring training
Spring trainingSpring training
Spring trainingTechFerry
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Hibernate Developer Reference
Hibernate Developer ReferenceHibernate Developer Reference
Hibernate Developer ReferenceMuthuselvam RS
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)hchen1
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android JetpackAhmad Arif Faizin
 
React Hooks Demystified: How to Effectively Use useCallback and useEffect
React Hooks Demystified: How to Effectively Use useCallback and useEffectReact Hooks Demystified: How to Effectively Use useCallback and useEffect
React Hooks Demystified: How to Effectively Use useCallback and useEffectTien Nguyen
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - Reactrbl002
 
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugToshiaki Maki
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsDror Bereznitsky
 
Annotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCAnnotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCJohn Lewis
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For ManagersAgileThought
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6Saltmarch Media
 
Dropwizard Introduction
Dropwizard IntroductionDropwizard Introduction
Dropwizard IntroductionAnthony Chen
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersJiaxuan Lin
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React NativeMuhammed Demirci
 

Similar to RIBs - Fragments which work (20)

Spring training
Spring trainingSpring training
Spring training
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Hibernate Developer Reference
Hibernate Developer ReferenceHibernate Developer Reference
Hibernate Developer Reference
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)
 
Spring boot
Spring bootSpring boot
Spring boot
 
The Best Way to Become an Android Developer Expert with Android Jetpack
The Best Way to Become an Android Developer Expert  with Android JetpackThe Best Way to Become an Android Developer Expert  with Android Jetpack
The Best Way to Become an Android Developer Expert with Android Jetpack
 
React Hooks Demystified: How to Effectively Use useCallback and useEffect
React Hooks Demystified: How to Effectively Use useCallback and useEffectReact Hooks Demystified: How to Effectively Use useCallback and useEffect
React Hooks Demystified: How to Effectively Use useCallback and useEffect
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
OttawaJS - React
OttawaJS - ReactOttawaJS - React
OttawaJS - React
 
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
 
Jdk Tools For Performance Diagnostics
Jdk Tools For Performance DiagnosticsJdk Tools For Performance Diagnostics
Jdk Tools For Performance Diagnostics
 
P20CSP105-AdvJavaProg.pptx
P20CSP105-AdvJavaProg.pptxP20CSP105-AdvJavaProg.pptx
P20CSP105-AdvJavaProg.pptx
 
Annotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVCAnnotation-Based Spring Portlet MVC
Annotation-Based Spring Portlet MVC
 
Patterns Are Good For Managers
Patterns Are Good For ManagersPatterns Are Good For Managers
Patterns Are Good For Managers
 
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
A Cocktail of Guice and Seam, the missing ingredients for Java EE 6
 
Dropwizard Introduction
Dropwizard IntroductionDropwizard Introduction
Dropwizard Introduction
 
Struts2 - 101
Struts2 - 101Struts2 - 101
Struts2 - 101
 
Developer Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for BeginnersDeveloper Student Clubs NUK - Flutter for Beginners
Developer Student Clubs NUK - Flutter for Beginners
 
JSAnkara Swift v React Native
JSAnkara Swift v React NativeJSAnkara Swift v React Native
JSAnkara Swift v React Native
 

Recently uploaded

Mobile App Development company Houston
Mobile  App  Development  company HoustonMobile  App  Development  company Houston
Mobile App Development company Houstonjennysmithusa549
 
BATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern
 
Technical improvements. Reasons. Methods. Estimations. CJ
Technical improvements.  Reasons. Methods. Estimations. CJTechnical improvements.  Reasons. Methods. Estimations. CJ
Technical improvements. Reasons. Methods. Estimations. CJpolinaucc
 
Building Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to startBuilding Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to startMaxim Salnikov
 
VuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckVuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckNaval Singh
 
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfFlutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfMind IT Systems
 
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...telebusocialmarketin
 
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsMUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsUniversity of Antwerp
 
Leveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevLeveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevpmgdscunsri
 
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityLarge Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityRandy Shoup
 
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...MyFAA
 
8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.Ritesh Kanjee
 
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurMinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurPriyadarshini T
 
User Experience Designer | Kaylee Miller Resume
User Experience Designer | Kaylee Miller ResumeUser Experience Designer | Kaylee Miller Resume
User Experience Designer | Kaylee Miller ResumeKaylee Miller
 
Boost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made EasyBoost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made Easymichealwillson701
 
Steps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic DevelopersSteps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic Developersmichealwillson701
 
Unlocking AI: Navigating Open Source vs. Commercial Frontiers
Unlocking AI:Navigating Open Source vs. Commercial FrontiersUnlocking AI:Navigating Open Source vs. Commercial Frontiers
Unlocking AI: Navigating Open Source vs. Commercial FrontiersRaphaël Semeteys
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...Maxim Salnikov
 
Einstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfEinstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfCloudMetic
 
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...jackiepotts6
 

Recently uploaded (20)

Mobile App Development company Houston
Mobile  App  Development  company HoustonMobile  App  Development  company Houston
Mobile App Development company Houston
 
BATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data MeshBATbern52 Swisscom's Journey into Data Mesh
BATbern52 Swisscom's Journey into Data Mesh
 
Technical improvements. Reasons. Methods. Estimations. CJ
Technical improvements.  Reasons. Methods. Estimations. CJTechnical improvements.  Reasons. Methods. Estimations. CJ
Technical improvements. Reasons. Methods. Estimations. CJ
 
Building Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to startBuilding Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to start
 
VuNet software organisation powerpoint deck
VuNet software organisation powerpoint deckVuNet software organisation powerpoint deck
VuNet software organisation powerpoint deck
 
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdfFlutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
Flutter the Future of Mobile App Development - 5 Crucial Reasons.pdf
 
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...
Telebu Social -Whatsapp Business API : Mastering Omnichannel Business Communi...
 
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow ModelsMUT4SLX: Extensions for Mutation Testing of Stateflow Models
MUT4SLX: Extensions for Mutation Testing of Stateflow Models
 
Leveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDevLeveling Up your Branding and Mastering MERN: Fullstack WebDev
Leveling Up your Branding and Mastering MERN: Fullstack WebDev
 
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of SimplicityLarge Scale Architecture -- The Unreasonable Effectiveness of Simplicity
Large Scale Architecture -- The Unreasonable Effectiveness of Simplicity
 
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
Take Advantage of Mx Tracking Flight Scheduling Solutions to Streamline Your ...
 
8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.8 Steps to Build a LangChain RAG Chatbot.
8 Steps to Build a LangChain RAG Chatbot.
 
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young EntrepreneurMinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
MinionLabs_Mr. Gokul Srinivas_Young Entrepreneur
 
User Experience Designer | Kaylee Miller Resume
User Experience Designer | Kaylee Miller ResumeUser Experience Designer | Kaylee Miller Resume
User Experience Designer | Kaylee Miller Resume
 
Boost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made EasyBoost Efficiency: Sabre API Integration Made Easy
Boost Efficiency: Sabre API Integration Made Easy
 
Steps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic DevelopersSteps to Successfully Hire Ionic Developers
Steps to Successfully Hire Ionic Developers
 
Unlocking AI: Navigating Open Source vs. Commercial Frontiers
Unlocking AI:Navigating Open Source vs. Commercial FrontiersUnlocking AI:Navigating Open Source vs. Commercial Frontiers
Unlocking AI: Navigating Open Source vs. Commercial Frontiers
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
 
Einstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdfEinstein Copilot Conversational AI for your CRM.pdf
Einstein Copilot Conversational AI for your CRM.pdf
 
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
03.2024_North America VMUG Optimizing RevOps using the power of ChatGPT in Ma...
 

RIBs - Fragments which work

  • 1. RIBs Fragments which work Dmitry Zaytsev, Android Engineer @ Uber 1
  • 3. 3
  • 6. ● Encapsulation ● Lifecycle ● Navigation Why Fragments
  • 9. ● Encapsulation ● Lifecycle ● Navigation ● Scalability Why not Fragments
  • 10. 10
  • 11. Listeners No compile-time safety A dynamic type check needs to be performed at runtime which could (and will) lead to crashes. override fun onAttach(context: Context) { super.onAttach(context) if (context is Listener) { listener = context } else if (parentFragment is Listener) { listener = parentFragment as Listener } else { throw RuntimeException() } }
  • 13. Back Stack Simple yet hard to use Back stack works well when you don’t need to handle back navigation yourself or use children fragments. However, as soon as you need to do any customization it quickly falls apart. // Attach Root fragment supportFragmentManager.beginTransaction() .apply { add(R.id.fragmentContainer, RootFragment.newInstance(), "Root") addToBackStack(null) } .commit() // Attach Child fragment rootFragment.childFragmentManager.beginTransaction() .apply { add(R.id.rootContainer, ChildFragment.newInstance(), null) addToBackStack(null) } .commit() // Press back
  • 15. ● Too many lifecycle states ● No compile-time safety when calling listeners ● Nested fragments is an afterthought ● Passing arguments ● Testability ● Non-restrictive API ● Fragments are an Android thing ● Requires glue code Problems
  • 16. 16
  • 17. 500+Mobile Engineers who worked on new Uber app 200+ Android Engineers who made at least 1 commint in Android monorepo 500+iOS Engineers who made at least 1 commit in iOS monorepo Some Numbers 17
  • 24. M - V - Something 24
  • 25. Naive MVP 25 Model Presenter View Update Read Notify Populate
  • 26. ● Works well for individual pieces ● Countless variations of the pattern ● Requires glue code ● Development slows down ● Integration points are main source of bugs Naive MVP / MVVM
  • 31. Naive MVP 31 Model Presenter View Update Read Notify Populate
  • 37. Interactor Simple Lifecycle Just 2 lifecycle events. Sometimes even less than that. @Override protected void didBecomeActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); // Subscribe to data source. Ready to update UI. } @Override protected void willResignActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); // Tear down and remove subscriptions/callbacks. }
  • 38. Interactor Business Logic Loads data from Model layer, makes decisions and asks Presenter to render UI. Talks to Router to perform navigation. @Override protected void didBecomeActive(@Nullable Bundle savedInstanceState) { super.didBecomeActive(savedInstanceState); presenter.showLoading(); productApi.getProducts() .observeOn(AndroidSchedulers.mainThread()) .as(autoDisposable(this)) .subscribe(result -> { presenter.hideLoading(); if (result.isSuccess()) { presenter.showProducts(result.getResult()); } else { presenter.showError(); } }); }
  • 39. Router Navigation Creates other RIBs and attaches them to view hierarchy. void routeToProductDetails(Product product) { ProductDetailsRouter router = productDetailsBuilder.build( getView(), product ); attachChild(router); getView().addView(router.getView()); }
  • 40. Builder Builds Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. public Router build() { // Builds and returns a router }
  • 41. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 42. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 43. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 44. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 45. Builder Configuration Instantiates Interactor, Router and View. Provides dependencies. Specifies which dependencies to request from a parent RIB. @Override protected ProductListView inflateView(LayoutInflater inflater, ViewGroup parentViewGroup) { return (ProductListView) inflater.inflate(R.layout.root_rib, parentViewGroup, false); } public interface ParentComponent extends ProductDetailsBuilder.ParentComponent { ProductNetworkApi productNetworkApi(); } @dagger.Module public abstract static class Module { @BindsInstance public abstract ProductDetailsInteractor.Listener productDetailsListener( ProductListInteractor interactor ); } @dagger.Component( modules = RootBuilder.Module.class, dependencies = ParentComponent.class ) interface Component extends InteractorBaseComponent<ProductListInteractor>, ProductDetailsBuilder.ParentComponent { // Dagger initialization }
  • 52. 52 Root Logged InLogged Out Map Balance StatusProfile Sign Up Log In
  • 53. 53 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In
  • 55. 55 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In RootActivity
  • 57. 57 Root Logged InLogged Out Map Balance StatusProfile Payments Sign Up Log In
  • 58. + 58
  • 62. ● Screen rotation ● Transition animations Not included
  • 63. Where to grab it? 63
  • 65. ● Good parts of MVP ● Composable ● Compile-time independent ● OS agnostic ● Scalable ● Single-Activity as a bonus Summary
  • 66. Thank you! Time for questions Dmitry Zaytsev, dmitry.zaytsev@uber.com Twitter: @dizaytsev Medium: @dmitry.zaicew