๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IOS๐ŸŽ/์•„ํ‚คํ…์ณ

[์•„ํ‚คํ…์ณ] RIBs๋ž€

by Jouureee 2022. 5. 6.

RIBs๋ž€ ์šฐ๋ฒ„์—์„œ ๋งŒ๋“  ์•„ํ‚คํ…์ณ์ž…๋‹ˆ๋‹ค. 

์‚ฌ์‹ค ์ž‘๋…„์— ํŠœํ† ๋ฆฌ์–ผ 1์„ ์กฐ๊ธˆ ๋”ฐ๋ผํ•ด๋ณด๊ธดํ–ˆ๋Š”๋ฐ .. ๋˜๊ฒŒ ๋ณต์žก๋ณต์žกํ–ˆ๋˜ ๊ธฐ์–ต๋งŒ ๋‚จ์•„์žˆ๋Š”๊ฑฐ ๊ฐ™์•„์š” ... 

๊ทธ๋ž˜์„œ RIBs๋ฅผ ์ด๋ฃจ๋Š” ๊ธฐ๋ณธ ๊ฐœ๋…์— ๋Œ€ํ•ด ํŠœํ† ๋ฆฌ์–ผ2๊นŒ์ง€ ๋ณด์•˜๊ฒ ๋‹ค ๋‹ค์‹œํ•œ๋ฒˆ ์ •๋ฆฌ ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค ์ด๋ฒˆ์— ํ”„๋กœ์ ํŠธ๋•Œ ๊ผญ ์ ์šฉํ•ด๋ณด๋ ค๊ตฌ์š” !!

 

What are RIBs For?

RIBs๋Š” ์šฐ๋ฒ„์˜ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์•„ํ‚คํ…์ณ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. RIBs๋Š” ๋งŽ์ด ์–ฝํ˜€์žˆ๋Š” state๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ํฐ ๋ชจ๋ฐ”์ผ ์•ฑ์„ ์œ„ํ•ด ๋””์ž์ธ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 

์šฐ๋ฒ„๋ฅผ ์œ„ํ•œ ์ด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋””์ž์ธ ํ• ๋•Œ ์•„๋ฆฌ ์›์น™์„ ์ค€์ˆ˜ํ•˜๊ณ ์ž ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

Encourage Cross-Platform Collaboration :

์šฐ๋ฆฌ ์•ฑ์˜ ๋ณต์žกํ•œ ๋ถ€๋ถ„์€ ๋Œ€๋ถ€๋ถ„ iOS์™€ Android์—์„œ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. RIBs๋Š” Android์™€ iOS๋ฅผ ์œ„ํ•œ ๋น„์Šทํ•œ ๊ฐœ๋ฐœ ํŒจํ„ด์„ ๋ณด์ž…๋‹ˆ๋‹ค. RIBs๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ iOS ๋ฐ Android ํ”Œ๋žซํผ์˜ ์—”์ง€๋‹ˆ์–ด๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๊ณต๋™์œผ๋กœ ์„ค๊ณ„๋œ ๋‹จ์ผ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Minimize Global States and Decisions:

Global state ๋ณ€ํ™”๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ํ–‰๋™์„ ๋งŒ๋“ค๊ณ  ๋ณ€ํ™”์— ๋Œ€ํ•œ ์ „์ฒด์˜ ์˜ํ–ฅ์„ ์•Œ์ง€ ๋ชปํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. RIBs๋Š” ๊ฐ RIBs์˜ ๊ณ ๋ฆฝ๋œ ๊นŠ์€ ๊ณ„์ธต๊ตฌ์กฐ ๋‚ด์—์„œ state๋ฅผ ์บก์Šํ™”ํ•˜์—ฌ global state ์ด์Šˆ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

 

Testability and Isolation:

ํด๋ž˜์Šค๋Š” ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์‰ฌ์›Œ์•ผ ํ•˜๊ณ  ๊ฒฉ๋ฆฌ(isolation)์— ๋Œ€ํ•ด ์ถ”๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ RIBs ํด๋ž˜์Šค๋Š” ๊ตฌ๋ณ„๋œ ์ฑ…์ž„์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. (i.e. routing, business logic, view logic, creation of other RIB classes) ์ถ”๊ฐ€๋กœ parent RIB ๋กœ์ง์€ child RIB ๋กœ์ง์œผ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ๋˜์–ด ์ง‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ RIB ํด๋ž˜์Šค๊ฐ€ ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์‰ฝ๊ณ  ์˜์กด์ ์ด์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๊ฒŒ ํ•˜๋Š”๋ฐ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

 

Tooling for Developer Productivity :

์ค‘์š”ํ•˜์ง€ ์•Š์€ ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์„ ์ฑ„ํƒํ•˜๋Š” ๊ฒƒ์€ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ ์—†์ด๋Š” ์†Œ๊ทœ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด์ƒ์œผ๋กœ ํ™•์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. RIB๋Š” ์ฝ”๋“œ ์ƒ์„ฑ, ์ •์  ๋ถ„์„ ๋ฐ ๋Ÿฐํƒ€์ž„ ํ†ตํ•ฉ๊ณผ ๊ด€๋ จ๋œ IDE ๋„๊ตฌ์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜๋ฉฐ, ์ด ๋ชจ๋‘๋Š” ํฌ๊ณ  ์ž‘์€ ํŒ€์˜ ๊ฐœ๋ฐœ์ž ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

 

Structured around Business Logic :

์•ฑ์˜ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ๊ตฌ์กฐ๋Š” UI์˜ ๊ตฌ์กฐ๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๋ฐ˜์˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, animation๊ณผ view performance๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด view ๊ณ„์ธต ๊ตฌ์กฐ๋Š” RIB ๊ณ„์ธต ๊ตฌ์กฐ๋ณด๋‹ค ์–•์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ํ•˜๋‚˜์˜ RIB์€ UI ๋‚ด์— ๋‹ค๋ฅธ ์œ„์น˜์— ๋‚˜ํƒ€๋‚˜๋Š” ์„ธ ๊ฐ€์ง€ view์˜ ๋ชจ์–‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

Explicit Contracts :

์š”๊ตฌ ์‚ฌํ•ญ์€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์•ˆ์ „ํ•œ contract์œผ๋กœ ์„ ์–ธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ข…์†์„ฑ๊ณผ ์ˆœ์„œ ์ข…์†์„ฑ์ด ์ถฉ์กฑ๋˜์ง€ ์•Š์œผ๋ฉด ํด๋ž˜์Šค๊ฐ€ ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ˆœ์„œ ์ข…์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ReactiveX๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. type ์•ˆ์ „ ์ข…์†์„ฑ ์ฃผ์ž…(DI) ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค ์ข…์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๊ณ , ๋งŽ์€ DI ๋ฒ”์œ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ถˆ๋ณ€์„ฑ ์ƒ์„ฑ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

 

Parts of a RIB

์˜ˆ์ „์— VIPER ์•„ํ‚คํ…์ณ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ–ˆ๋‹ค๋ฉด, RIB์˜ ํด๋ž˜์Šค ๋ถ„์„์ด ์นœ์ˆ™ํ•ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. RIB๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ ๋ชจ๋“  ์š”์†Œ๋Š” ์ž์ฒด ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

Interactor

๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Rx subscription์„ ์ˆ˜ํ–‰ํ•˜๊ณ , state-altering decision์„ ๋งŒ๋“ค๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋””์— ์ €์žฅํ• ์ง€ ๊ฒฐ์ •ํ•˜๊ณ  ๋‹ค๋ฅธ RIBs๋“ค์„ ์ž์‹์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

 

Interactor์— ์˜ํ•ด ์ˆ˜ํ–‰๋˜๋Š” ๋ชจ๋“  operation์€ lifecycle์— ๊ตญํ•œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Interactor๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ์—๋งŒ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์‹คํ–‰๋˜๋„๋ก ๋„๊ตฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Interator๊ฐ€ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์•˜์ง€๋งŒ subscription์€ ์›์น˜ ์•Š์€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด๋‚˜ UI ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์Šต๋‹ˆ๋‹ค.

 

Router

Interactor๋ฅผ listenํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฌผ์„ ์ž์‹ RIBs์— ๊ฐ€์ง€๊ณ  ๋–ผ๋Š”(detach) ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค. Router๋Š” ์•„๋ž˜ 3๊ฐ€์ง€ ์ด์œ ๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

 1. router๋Š” Humble Object์ฒ˜๋Ÿผ ํ–‰๋™ํ•œ๋‹ค. ๊ทธ๊ฒƒ์€ ํ…Œ์ŠคํŠธ ๋ณต์žกํ•œ Interactor ๋กœ์ง์„ child interactor๋ฅผ mockํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ care๋ฅผ ํ•„์š”ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋ฉด์„œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค. 


2. router๋Š” parent interactor์™€ ๊ทธ child interactor ์‚ฌ์ด ์ถ”์ƒํ™”๋œ ๊ณ„์ธต์„ ๋งŒ๋“ ๋‹ค. ์ด๊ฒƒ์€ Interactors ๊ฐ„์˜ ๋™๊ธฐ์‹ ํ†ต์‹ ์„ ์กฐ๊ธˆ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ณ  RIB ๊ฐ„์˜ ์ง์ ‘ ์—ฐ๊ฒฐ ๋Œ€์‹  ๋ฐ˜์‘ํ˜• ํ†ต์‹ ์˜ ์ฑ„ํƒ์„ ๊ฒฉ๋ คํ•œ๋‹ค.


3. Interactor์— ์˜ํ•ด ๊ตฌํ˜„๋˜๋Š” ๋‹จ์ˆœํ•˜๊ณ  ๋ฐ˜๋ณต์ ์ธ ๋ผ์šฐํŒ… ๋กœ์ง์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ์ด๊ฒƒ์€ Interactor๋ฅผ ์ž‘๊ฒŒ ์œ ์ง€ํ•˜๊ณ  RIB์—์„œ ์ œ๊ณตํ•˜๋Š” ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋” ์ง‘์ค‘ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค€๋‹ค.

 

Builder

Builder์˜ ์ฑ…์ž„์€ ๋ชจ๋“  RIB์˜ ๊ตฌ์„ฑ ํด๋ž˜์Šค์™€ ๊ฐ RIB์˜ ์ž์‹์— ๋Œ€ํ•œ ๋นŒ๋”๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
Builder์•ˆ์—์„œ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์€ iOS์— mockability๋ฅผ ์ง€์›ํ•˜๊ณ  ๋‚˜๋จธ์ง€ RIB ์ฝ”๋“œ๋“ค์„ DI ๊ตฌํ˜„์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์— ๋ฌด๊ด€์‹ฌํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. builder๋Š” ์˜ค์ง RIB์˜ ์ผ๋ถ€๋ถ„์œผ๋กœ ํ”„๋กœ์ ํŠธ์—์„œ ์“ฐ์ด๋Š” DI ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋ฅธ builder๋ฅผ ๊ตฌํ˜„ํ•จ์œผ๋กœ์„œ ๋‹ค๋ฅธ DI ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ด ํ”„๋กœ์ ํŠธ์—์„œ ๋‚˜๋จธ์ง€ RIB ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

Presenter

๋น„์ง€๋‹ˆ์Šค ๋ชจ๋ธ์„ ๋ทฐ๋ชจ๋ธ๋กœ ๋˜๋Š” ๋ทฐ๋ชจ๋ธ์„ ๋น„์ง€๋‹ˆ์Šค ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ƒํƒœ ์—†๋Š”(stateless) ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ๋ทฐ๋ชจ๋ธ ๋ณ€ํ™˜ ํ…Œ์ŠคํŠธ๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋ณ€ํ™˜์€ ์ž์ฃผ ํ•˜์ฐฎ์€๋ฐ ์ด๊ฒƒ์€ dedicated presenter ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. presenter๊ฐ€ ์ƒ๋žต๋˜๋ฉด ๋ทฐ๋ชจ๋ธ์„ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์€ view ๋˜๋Š” interactor์˜ ์ฑ…์ž„์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

View(Controller)

view๋Š” UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ธ์Šคํ„ด์Šคํ™”, ๋ ˆ์ด์•„์›ƒ, ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜ ํ•ธ๋“ค๋ง, ๋ฐ์ดํ„ฐ์™€ animation๊ณผ ํ•จ๊ป˜ UI ์ปดํฌ๋„ŒํŠธ ์ฑ„์šฐ๊ธฐ ๋“ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. View๋Š” ๊ฐ€๋Šฅํ•œ dumbํ•˜๊ฒŒ ๋””์ž์ธ ๋˜์–ด์ง€๋Š”๋ฐ, ์˜ค์ง information์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์œ ๋‹›ํ…Œ์ŠคํŠธ ๋˜์–ด์งˆ ํ•„์š”๊ฐ€ ์—†๋Š” ์ฝ”๋“œ๋“ค์„ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

Component

RIB์˜ dependencies๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋นŒ๋”๊ฐ€ RIB๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋‹ค๋ฅธ ๋‹จ์œ„๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. RIB๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์™ธ๋ถ€ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ RIB ์ž์ฒด์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ข…์†์„ฑ์„ ์†Œ์œ ํ•˜๊ณ  ๋‹ค๋ฅธ RIB์—์„œ ์ด์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ๋ถ€๋ชจ RIB์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถ€๋ชจ RIB์˜ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ์ž์‹ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ RIB์˜ ๋นŒ๋”์— ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค. 

๋Œ“๊ธ€