RIBs - Tutorial 0

Zion·2022년 1월 23일
1

RIBs

목록 보기
1/1
post-thumbnail

안녕하시렵니까?

RIBs에 대해 포스팅을 해보려 합니다.

현재는 tutorial3까지 진행한 상태입니다!
중간에 점검할겸 이제서야 키보드를 붙잡고 포스팅 해보겠습니다.

지금까지 RIBs tutorial을 따라해보면서 한 생각은.
깔끔해요. 맡은바 기능을 충실히(?) 해주는거같아요.
비지니스로직을 처리해주는곳, 뷰를 처리해주는 곳 등등 역할 분담이 잘 돼 있다는 생각이 들었습니다.
혼자서 이걸 짤 수 있을까 라고 생각해봤는데 음 그건 아직은 못하겠습니다.
짤 수 있을때가 되면 글을 수정해보겠습니다!

What are RIB for?

RIBs는 Uber의 cross-platform architecture framework 입니다. 많은 상태들을 포함하고 있는 큰 규모의 mobile application들을 위해 디자인된 프레임워크입니다.

Encourage Cross-Platform Collaboration:
Most of the complex parts of our apps are similar on both iOS and Android. 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.
우리 앱의 복잡한 부분은 대부분 iOS와 Android에서 비슷합니다. RIB는 안드로이드와 iOS에 대해 비슷한 개발 패턴을 보여줍니다. RIB를 사용함으로써, iOS와 Android 플랫폼 모두에서 엔지니어는 기능을 위해 공동 설계된 단일 아키텍처를 공유할 수 있습니다.

Minimize Global States and Decisions:
Global state changes cause unpredictable behavior and can make it impossible for engineers to know the full impact of their changes. RIBs encourage encapsulating states within a deep hierarchy of well-isolated individual RIBs, thus avoiding global state issues.
글로벌 상태 변경은 예측할 수 없는 동작을 유발하며 엔지니어가 변경사항이 미치는 전체 영향을 알지 못하게 할 수 있습니다. RIB는 잘 격리된 개별 RIB의 심층 계층 내에서 캡슐화 상태를 장려하여 글로벌 상태 문제를 방지합니다.

Testability and Isolation:
Classes must be easy to unit test and reason about in isolation. Individual RIB classes have distinct responsibilities (i.e. routing, business logic, view logic, creation of other RIB classes). In addition to that, parent RIB logic is mostly decoupled from its child RIB logic. This makes RIB classes easy to test and reason about independently.
Tooling for Developer Productivity: 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.
클래스는 단위 테스트가 쉬워야 하고 개별적으로 추론해야 합니다. 개별 RIB 클래스에는 고유한 책임이 있습니다 (i.e. routing, business logic, view logic, creation of other RIB classes). 그 외에도 상위 RIB 논리는 대부분 하위 RIB 논리에서 분리됩니다. 따라서 RIB 클래스를 쉽게 테스트하고 독립적으로 추론할 수 있습니다.
개발자 생산성을 위한 도구: 중요하지 않은 아키텍처 패턴을 채택하는 것은 강력한 도구 없이는 소규모 애플리케이션 이상으로 확장되지 않습니다. RIB는 코드 생성, 정적 분석 및 런타임 통합과 관련된 IDE 도구와 함께 제공되며, 이 모두는 크고 작은 팀의 개발자 생산성을 향상시킵니다.

Open-Closed Principle:
Whenever possible, developers should be able to add new features without modifying existing code. This can be seen in a few places when using RIBs. For example, you can attach or build a complex child RIB that requires dependencies from its parent with almost no changes to the parent RIB.
가능하면 개발자는 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있어야 합니다. 이것은 RIB를 사용할 때 몇 군데에서 볼 수 있습니다. 예를 들어, 상위 RIB를 거의 변경하지 않고 상위로부터 종속성을 필요로 하는 복잡한 하위 RIB를 연결하거나 빌드할 수 있습니다.

Structured around Business Logic:
The app’s business logic structure should not need to strictly mirror the structure of the UI. For example, to facilitate animations and view performance, the view hierarchy may want to be shallower than the RIB hierarchy. Or, a single feature RIB may control the appearance of three views that appear at different places in the UI.
Explicit Contracts: Requirements should be declared with compile-time safe contracts. A class should not compile if its class dependencies and ordering dependencies are not satisfied. We use ReactiveX to represent ordering dependencies, type safe dependency injection (DI) systems to represent class dependencies and many DI scopes to encourage the creation of data invariants.
앱의 비즈니스 로직 구조는 UI의 구조를 엄격하게 미러링할 필요가 없습니다. 예를 들어, 애니메이션과 보기 성능을 용이하게 하기 위해 보기 계층 구조는 RIB 계층 구조보다 얕을 수 있습니다. 또는 단일 기능 RIB가 UI의 다른 위치에 나타나는 세 가지 보기의 모양을 제어할 수 있습니다.
명시적 계약: 요구 사항은 컴파일 시간에 안전한 계약으로 선언되어야 합니다. 클래스 종속성과 순서 종속성이 충족되지 않으면 클래스가 컴파일되지 않아야 합니다. ReactiveX를 사용하여 순서 종속성을 나타내고, DI(유형 안전 종속성 주입) 시스템을 사용하여 클래스 종속성을 나타내고, 많은 DI 범위를 사용하여 데이터 불변성 생성을 권장합니다.

Parts of a RIB


우와 이게 뭐야 할 수 있습니다. 제가 그랬거든요.

제가 지금 3까지 한 상태라 눈에 들어오는걸수도 있는데, 뭐가 뭔진 모르겠지만 떨지말고 일단 그림만 봐봅시다.

밑에 있는 Builder가 'Router, Interactor, Presenter, View들을 찌르고 있네요.
Component를 가지고 Builder가 RIB클래스를 만들어줘요.
이 립을 Router, Interactor, Presenter, View들이 각각 역할에 맞게 사용해줄꺼에요.

뭔가 너무 뜬구름같다고 느낀다면 이 그림을 봐볼까요.

앱의 플로우를 트리형태로 나타낸겁니다. 와 깔끔하네요? 네모 하나하나들이 RIB입니다.

다시 돌아와서.
그렇담 저기 회색글씨로 써져있는 Component들이 RIB안에서 어떻게 기능하는지 봐봅시다.

Builder에서 만든 립을 가지고 Router, Interactor, View(Controller)들이 기능하는걸 도식화한겁니다.

Interactor

Interactor에는 비즈니스 로직이 포함되어 있습니다. 여기에서 Rx subscriptions을 수행하고, 상태 변경 결정을 내리고, 데이터를 저장할 위치를 결정하고, 자식으로 연결해야 하는 다른 RIB를 결정합니다.

Interactor가 수행하는 모든 작업은 해당 lifecycle로 제한되어야 합니다. Interactor가 활성 상태일 때만 비즈니스 로직이 실행되도록 하는 도구를 구축했습니다. 이렇게 하면 Interactor가 비활성화되지만 구독이 계속 실행되고 비즈니스 로직 또는 UI 상태에 대한 원치 않는 업데이트가 발생하는 시나리오를 방지할 수 있습니다.

Router

Router는 Interactor를 듣고 출력을 자식 RIB을 연결 및 분리합니다. Router는 세 가지 간단한 이유로 존재합니다.

Router는 자식 Interactor를 따라하거나 다른 방식으로 존재 여부를 신경 쓸 필요 없이, 복잡한 Interactor 로직을 더 쉽게 테스트할 수 있도록 하는 Humble Objects 역할을 합니다.
Router는 부모 Interactor와 자식 Interactor 사이에 추가 추상화 계층을 만듭니다. 이것은 Interactors 간의 동기식 통신을 조금 더 어렵게 만들고 RIB 간의 직접 연결 대신 반응형 통신의 채택을 권장합니다.
라우터에는 Interactor에 의해 구현되는 단순하고 반복적인 라우팅 로직이 포함되어 있습니다. 이 상용구 코드를 제외하면 Interactors를 작게 유지하고 RIB에서 제공하는 핵심 비즈니스 로직에 더 집중하는 데 도움이 됩니다.
빌더의 책임은 모든 RIB의 구성 클래스와 각 RIB의 자식에 대한 빌더를 인스턴스화하는 것입니다.

Builder에서 클래스 생성 로직을 분리하면 iOS에서 모의 가능성에 대한 지원이 추가되고 나머지 RIB 코드는 DI 구현의 세부 사항에 무관심해집니다. Builder는 프로젝트에 사용된 DI 시스템을 인식해야 하는 RIB의 유일한 부분입니다. 다른 빌더를 구현하면 다른 DI 메커니즘을 사용하여 프로젝트에서 나머지 RIB 코드를 재사용할 수 있습니다.

Presenter

Presenter는 비즈니스 모델을 뷰 모델로, 또는 그 반대로 변환하는 상태 비저장 클래스입니다. 뷰 모델 변환 테스트를 용이하게 하는 데 사용할 수 있습니다. 그러나 종종 이 변환은 너무 간단해서 전용 Presenter 클래스를 만들 필요가 없습니다. Presenter가 생략되면 View Model을 번역하는 것은 View(Controller)나 Interactor의 책임이 됩니다.

View(Controller)

View는 UI를 빌드하고 업데이트합니다. 여기에는 UI 구성 요소 인스턴스화 및 레이아웃, 사용자 상호 작용 처리, 데이터로 UI 구성 요소 채우기 및 애니메이션이 포함됩니다. 보기는 가능한 한 "dumb"한 것으로 설계되었습니다. 그들은 단지 정보를 표시합니다. 일반적으로 단위 테스트가 필요한 코드는 포함되어 있지 않습니다.

Component

Components는 RIB 종속성(dependencies)을 관리하는 데 사용됩니다. 이들은 Builder가 RIB를 구성하는 다른 단위를 인스턴스화하도록 지원합니다. Components는 RIB를 구축하는 데 필요한 외부 종속성에 대한 액세스를 제공할 뿐만 아니라 RIB 자체에 의해 생성된 종속성을 소유하고 다른 RIB에서 이에 대한 액세스를 제어합니다. 상위 RIB의 구성요소는 일반적으로 상위 RIB의 종속성에 대한 하위 액세스를 제공하기 위해 하위 RIB의 빌더에 주입됩니다.

잠깐만요...

읽다보니 모르겠네요.
Dependency Injection 공부하고 다시 올게요!😅

profile
어제보다만 나아지는

0개의 댓글