RIB is the cross-platform architecture framework designed by uber for mobile apps with a large number of engineers and nested states. RIB is short for Router(rouring between RIBS), Interactor(contains business logic), and Builder(instantiate all the RIB’s constituent classes) which are core components of this architecture. RIB is famous for its high SOC and state handling.
In this article, I want to talk about the advantages of RIB in general. In the next articles, I explain how RIB implements these advantages and how to use RIB architecture and framework in android.
Why uber decided to create RIB ?
According to the uber-blog, they had many reasons to create RIBs architecture and framework which you can see them below.
As the uber mobile code base grows and new features are added quickly, the technical debt was extremely high and they could not practically add a new product.
According to Uber, many products were added to the app quickly , which were different for each country. Some countries even had several additional features compared to other countries, and previous products changed, making it virtually impossible to add products in the end. Or update.
Ride-hailing apps have many states, and handling these states is not an easy task in common mobile architectures.
Uber already knew that writing a new framework and architecture would take time, so before that, it researched most of the designs pattern and concluded that they each had a problem, and decided to create RIB.
- State Handling
- Cross platform
We designed RIBs to encourage code isolation, letting each team, feature, or component have its own workspace.
In RIB, each feature can have a view or it can be view-less. Each feature contains the main elements of RIB router, interactor, builder, and view (if not view-less). Each feature provides dependencies from the parent with a simple interface and the source code dependencies can only point inwards. If in a large team SOC between features is well provided, each team can work exclusively on one feature without affecting the work of other teams. Below you can see RIB features or products in the app like uber driver.
As we mentioned above Ride-hailing apps has many states so another reason to create RIB by uber is state-handling.
There is three commons ways for handling states.
- HFSM (Hierarchical Finite State Machine)
- FSM (Finite State Machine)
- BT (Bahavior Trees)
HFSM and FSM
Base on Wikipedia HFSM or FSM is A finite-state machine or simply a state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The HFSM or FSM can change from one state to another in response to some inputs; the change from one state to another is called a transition. the only difference between HFSM and FSM is that HFSM reduces transactions by seprating 2 or more states into a group of states. HFSM and FSM have many disadvantages which you can see below.
- FSM : N States. so N * N possible transactions
every state can transition to another states with no limitation.
when adding or removing a state, it is necessary to change the conditions of all other states that have transition to the new or old one. Big changes are more susceptible to errors that may pass unnoticed.
FSMs with many states lose the advantage of graphical readability, becoming a nightmare of boxes and arrows.
as the conditions are inside the states, the coupling between the states is strong, being practically impossible to use the same behavior in multiple projects.
BT (Bahavior Trees)
Based on Wikipedia BT is A behavior tree is a mathematical model of plan execution. They describe switchings between a finite set of tasks in a modular fashion. Their strength comes from their ability to create very complex tasks composed of simple tasks, without worrying how the simple tasks are implemented. Below you can see the advantages and disadvantages of BT.
Behavior Trees use the concept of Tick(events), a signal that is sent in a fixed frequency, which starts from the root node and is propagated to its children. By doing this Behavior Trees can react in real-time to events that happen in the world.
transitions in BT are defined by the structure, not by conditions inside the states. Because of this, nodes can be designed independent from each other, thus, when adding or removing new nodes (or even subtrees) in a small part of the tree, it is not necessary to change other parts of the model
when a BT have many nodes, it can be decomposed into small sub-trees saving the readability of the graphical model
due to the independence of nodes in BT, the subtrees are also independent. This allows the reuse of nodes or subtrees among other trees or projects.
- Always start from root node
- This isn’t a very efficient way to do things, especially when the behavior tree gets deeper as its developed and expanded during development
As you may guess uber uses BT in RIB architecture. The app is divided into different RIBs (units) and form a BT tree.
RIBs present similar development patterns for Android and iOS. By using RIBs, engineers across both iOS and Android platforms can share a single, co-designed architecture for their features.
Adopting non-trivial architectural patterns does not scale beyond small applications without robust tooling. RIBs come with IDE tooling around code generation, static analysis, and runtime integrations. all of which improve developer productivity for large and small teams. Below you can see open source tools.
- Code Generation for Android Studio
- NPE Static analytis for android
- Autodispose static analytics for android
Like other tools, RIB has disadvantages, which I will discuss in a separate article in the future.