iOS ๐ŸŽ/iOS

RxSwift : ๋“ค์–ด๊ฐ€๊ธฐ์— ์•ž์„œ

yongmin.Lee 2021. 5. 16. 17:01

 

๋ช…๋ นํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ((Imperative programming)

  •  ๋ฌด์—‡(What)์„ ํ•  ๊ฒƒ์ธ์ง€ ๋‚˜ํƒ€๋‚ด๊ธฐ๋ณด๋‹ค ์–ด๋–ป๊ฒŒ(How) ํ•  ๊ฑด์ง€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ์‹
  • ์ ˆ์ฐจ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ: ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ์ˆœ์ฐจ์ ์ธ ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ํฌํ•จํ•˜๋Š” ๋ฐฉ์‹ (C, C++)
  • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ: ๊ฐ์ฒด๋“ค์˜ ์ง‘ํ•ฉ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ํ‘œํ˜„ (C++, Java, C#)

 

์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ(declarative programming)

  • ์–ด๋–ป๊ฒŒ ํ• ๊ฑด์ง€(How)๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ๋ณด๋‹ค ๋ฌด์—‡(What)์„ ํ•  ๊ฑด์ง€๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ์‹
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ: ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ฅผ ์กฐํ•ฉํ•˜๊ณ  ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹ (ํด๋กœ์ €, ํ•˜์Šค์ผˆ, ๋ฆฌ์Šคํ”„)

 

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • ํ•จ์ˆ˜(function)๋ฅผ ์ด์šฉํ•ด์„œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ ์—†๋„๋ก ์„ ์–ธํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ
  • ํ”„๋กœ๊ทธ๋žจ์ด ์ƒํƒœ์˜ ๋ณ€ํ™” ์—†์ด ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ•™์  ํ•จ์ˆ˜ ๊ณ„์‚ฐ์œผ๋กœ ์ทจ๊ธ‰
  • ์ˆœ์ˆ˜ํ•˜๊ฒŒ ํ•จ์ˆ˜์— ์ „๋‹ฌ๋œ ์ธ์ž๊ฐ’๋งŒ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์ฃผ๋ฏ€๋กœ ์ƒํƒœ๊ฐ’์„ ๊ฐ–์ง€ ์•Š๊ณ  ์ˆœ์ˆ˜ํ•˜๊ฒŒ ํ•จ์ˆ˜๋กœ๋งŒ ๋™์ž‘
  • ์–ด๋–ค ์ƒํ™ฉ์—์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋”๋ผ๋„ ์ผ์ •ํ•˜๊ฒŒ ๊ฐ™์€ ๊ฒฐ๊ณผ ๊ฐ’ ๋„์ถœ ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ๊ฐ๊ฐ ์ƒํ˜ธ ๊ฐ„์„ญ์—†์ด ๋ฐฐํƒ€์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค
  • ํ•„์š”ํ•œ ๋งŒํผ ํ•จ์ˆ˜๋ฅผ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์Šค์ผ€์ผ์—… ํ•  ์ˆ˜ ์žˆ๊ธฐ๋•Œ๋ฌธ์— ๋Œ€๊ทœ๋ชจ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ์— ๊ฐ•์ ์ด ์žˆ๋‹ค
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์žฅ์ 
    • ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์—ฐ์‚ฐ์ฒ˜๋ฆฌ ์ž‘์—…์ด ๋™์‹œ์— ์ผ์–ด๋‚˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค๊ธฐ ์‰ฝ๋‹ค
    • ๋ฉ€ํ‹ฐ ์ฝ”์–ด ํ˜น์€ ์—ฌ๋Ÿฌ ๊ฐœ ์—ฐ์‚ฐ ํ”„๋กœ์„ธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ์—์„œ ํšจ์œจ์ ์ธ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค๊ธฐ ์‰ฝ๋‹ค
    • ์ƒํƒœ๋ณ€ํ™”์— ๋”ฐ๋ฅธ ๋ถ€์ž‘์šฉ์—์„œ ์ž์œ ๋กœ์›Œ์ง€๋ฏ€๋กœ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๊ธฐ๋Šฅ๊ตฌํ˜„์— ์ดˆ์ ์„ ๋งž์ถฐ ์„ค๊ณ„๊ฐ€๋Šฅ

 

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŠน์ง•

  • ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด(First-class object)๋กœ ๋‹ค๋ฃฌ๋‹ค
    • ์ผ๊ธ‰๊ฐ์ฒด๋Š” ์ „๋‹ฌ์ธ์ž๋กœ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ๋‹ค
    • ์ผ๊ธ‰๊ฐ์ฒด๋Š” ๋™์  ํ”„๋กœํผํ‹ฐ ํ• ๋‹น์ด ๊ฐ€๋Šฅ
    • ์ผ๊ธ‰๊ฐ์ฒด๋Š” ๋ณ€์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์•ˆ์— ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค
    • ์ผ๊ธ‰๊ฐ์ฒด๋Š” ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
    • ์ผ๊ธ‰๊ฐ์ฒด๋Š” ํ• ๋‹นํ• ๋•Œ ์‚ฌ์šฉ๋œ ์ด๋ฆ„๊ณผ ๊ด€๊ณ„์—†์ด ๊ณ ์œ ํ•œ ๊ฐ์ฒด๋กœ ๊ตฌ๋ณ„ ๊ฐ€๋Šฅ
  • ๊ณ ์ฐจํ•จ์ˆ˜ (High-orde Function)
    • ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ๋กœ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๊ฑฐ๋‚˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
    • ์Šค์œ„ํ”„ํŠธ์—์„œ ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰๊ฐ์ฒด๋กœ ์ทจ๊ธ‰๋˜๊ธฐ์— ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์‚ฌ์šฉ๋ ์ˆ˜ ์žˆ๋‹ค
    • ์ด๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜์˜ ๋‚ด๋ถ€์ฝ”๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ์™ธ๋ถ€์—์„œ ์‹คํ–‰ ํ๋ฆ„์„ ์ถ”๊ฐ€ํ• ์ˆ˜ ์žˆ๊ฒŒ๋˜๋ฉฐ ํ•จ์ˆ˜์˜ ์žฌํ™œ์šฉ์„ฑ, ์žฌ์‚ฌ์šฉ์„ฑ์ด ์ฆ๊ฐ€
  • ๋ถˆ๋ณ€์„ฑ (Immutablility)
    • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ•  ์ˆ˜ ์—†๋Š”๋ฐ, ์ด๋ฅผ ๋ถˆ๋ณ€์„ฑ ๋ฐ์ดํ„ฐ๋ผ๊ณ  ํ•œ๋‹ค. 
    • ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ์›๋ณธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด ๊ทธ ์ผ๋ถ€๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ , ๋ณ€๊ฒฝํ•œ ๋ณต์‚ฌ๋ณธ์„ ์‚ฌ์šฉํ•ด ์ž‘์—…์„ ์ง„ํ–‰ํ•œ๋‹ค.
    • ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ : ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด ๋ฐ์ดํ„ฐ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“ค์–ด ์ฃผ๋Š” ๋„๊ตฌ๋“ค์ด ํ•„์š”ํ•˜๋‹ค.
    • ๊ฐ€๋ณ€ ๋ณ€์ˆ˜์— ์˜ํ•ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝํ•ฉ(race)์กฐ๊ฑด, ๊ต์ฐฉ์ƒํƒœ(deadlock), ๋™์‹œ ์—…๋ฐ์ดํŠธ(concurrent update)๋ฌธ์ œ๋กœ๋ถ€ํ„ฐ ์ž์œ ๋กญ๋‹ค.
  • ์ˆœ์ˆ˜ ํ•จ์ˆ˜ (Pure function)
    • ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ž€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ํ•„์š”ํ•œ ๊ฐœ๋…์œผ๋กœ ์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋œปํ•œ๋‹ค.
    • ๋™์ผํ•œ ์ž…๋ ฅ์—๋Š” ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.
    • ํ•จ์ˆ˜์˜ ์‹คํ–‰์€ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค. (Side effect ๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค)

 

Reactive Programming, ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • Reactive Programming์€ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๊ธฐ๋ฐ˜์„ ๋‘๊ณ  ๊ทธ๊ฒƒ์— ๋ฐ˜์‘ํ•ด์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ• ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„
  • ๋น„๋™๊ธฐ์ ์ธ ๋ฐ์ดํ„ฐ ํ๋ฆ„๊ณผ ๊ทธ ๋ณ€ํ™”๋Š” ๋งˆ์น˜ ๊ฐ•๊ณผ ๊ฐ™์•„์„œ ์ด๋ฅผ ๊ด€์ฐฐํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ๋ฆ„์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ํ๋ฆ„๊ณผ ๋ณ‘ํ•ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค
  • ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ Functional Programming์„ ํ™œ์šฉ
    => ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์— ์‰ฝ๊ฒŒ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๊ณ  ์ด๋ฒคํŠธ๋“ค์˜ ์ˆœ์„œ,์žฌ์‚ฌ์šฉ์„ฑ์„ ํ–ฅ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค 
    => ๋น„๋™๊ธฐ์‹(์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ง„ํ–‰) ํ™œ๋™์„ ์‰ฝ๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค
  • ์Šค์œ„ํ”„ํŠธ๋Š” Reactive Programming์„ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ ์ œ๊ณต
    • @escaping  : handler to catch the end point of asynchoronous task
    • Dispatchqueue : For making task asynchoronously
    • willSet, didSet  :  makes observing specific variable reactively

 

RxSwift

    • RxSwift = Reactive eXtensions + Swift
    • Rx๋Š” Reactive Programming ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๋˜์–ด์žˆ๋Š” API 
    • RxSwift๋ฅผ ์ด์šฉํ•˜๋ฉด Reactive Programming ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, RxSwift ์ด์šฉ์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ๋‹ค
      • RxSwift makes reactive code readable and short
        -> You donโ€™t need to use those Dispatchqueue, willSet, and DidSet
      • RxSwift operators make stream extensive
๋Œ“๊ธ€์ˆ˜0