iOS/๐Ÿค– App

[iOS] Dependency Injection (์˜์กด์„ฑ ์ฃผ์ž…) ์ด๋ž€?

woozzang 2021. 6. 20. 16:48

1์ฐจ ์ˆ˜์ •: 21.08.11
2์ฐจ ์ˆ˜์ •: 21.09.27



์•ˆ๋…•ํ•˜์„ธ์š” ๐Ÿถ
์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ํ”ํžˆ DI ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์˜์กด์„ฑ ์ฃผ์ž…์— ๋Œ€ํ•˜์—ฌ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณผ๊ฒŒ์š”!!!๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ


Injection

Dependency Injection means giving an objects its instance variable.
Really. That's it - James Shore


์œ„ ๋ฌธ์žฅ์€ ์˜์กด์„ฑ ์ฃผ์ž…์— ๋Œ€ํ•ด ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…๋ฃŒํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฐœ๋…์„ ์„ค๋ช…ํ•  ๋•Œ ์ž์ฃผ ๋“ฑ์žฅํ•˜๋Š” ์ธ์šฉ๋ฌธ์ธ ๊ฒƒ ๊ฐ™์•„์š”!

Dependency Injection ์€
A ๋ผ๋Š” ๊ฐ์ฒด์˜ ์†์„ฑ์„ A๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ์ดˆ๊ธฐํ™”ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
์™œ ์Šค์Šค๋กœ ํ•˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ ์ดˆ๊ธฐํ™”ํ•ด์•ผ๋งŒ ํ• ๊นŒ์š”??

๊ฒฐ๋ก ๋ถ€ํ„ฐ ์‚ดํŽด๋ณด์ž๋ฉด:
๊ฐ์ฒด๊ฐ„ ๊ฒฐํ•ฉ์„ ๋Š์Šจํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„์™€ ๊ฐ™์€ ์˜๋ฏธ์ง€๋งŒ, ์ข€ ๋” ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•ด์ง€๊ณ  ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฃผ์ž…๋ฐ›๋Š” ์†์„ฑ์˜ ํƒ€์ž…์„ ํ”„๋กœํ† ์ฝœ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์šฉ์ดํ•ด์ง€๊ณ , ์˜๋„๊ฐ€ ๋ช…ํ™•ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์šฐ์„  ๋‹จ์–ด๋“ค์˜ ์ •์˜๋ถ€ํ„ฐ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!!!


์˜์กด์„ฑ?

๊ฐ์ฒด ์ง€ํ–ฅ์˜ ํ˜‘๋ ฅ์€ ์—ฐ์†๋œ ์š”์ฒญ๊ณผ ์‘๋‹ต์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.


DI ์˜ D ๋Š” Dependency, ์ฆ‰ ์˜์กด์„ฑ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
์˜์กด์„ฑ์€ UML ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์˜์กด ๊ด€๊ณ„์— ๋Œ€ํ•ด ๊ฒ€์ƒ‰ํ•ด๋ณด์„ธ์š”!

์˜์กด ๊ด€๊ณ„๋Š” ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด A ๋ผ๋Š” ํด๋ž˜์Šค๊ฐ€ ์—ฐ์‚ฐ์— B๋ผ๋Š” ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ (๋ฉ”์„œ๋“œ) ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด
A๋Š” B์— ์˜์กด๊ด€๊ณ„๊ฐ€ ์žˆ์œผ๋ฉฐ, ์˜์กด์„ฑ์ด ์ƒ๊ฒผ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class A { func hasDependency() -> Int { return B.default.someFunction() // B ํด๋ž˜์Šค์˜ ์‹ฑ๊ธ€ํ†ค์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. } // A ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’์ด B ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜๊ฐ’์— ๋”ฐ๋ผ ๋ฐ”๋€Œ๋ฏ€๋กœ ์˜์กดํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. }

์ž ๊น, ๊ธ€์“ด์ด๋Š” ์•„์ง ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿค”

>> ์ด ๋ถ€๋ถ„์€ ์˜์กด์„ฑ ์ฃผ์ž…์„ ์ฒ˜์Œ ๊ณต๋ถ€ํ•˜์‹œ๋Š” ๋ถ„์ด๋ฉด ๋„˜์–ด๊ฐ€๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. <<

๋”๋ณด๊ธฐ

์œ„ ์ฝ”๋“œ์—๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๊ณตํ•™์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ํ‘œํ˜„๋˜๋Š”

'์˜์กด ๊ด€๊ณ„ (dependency) '๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๋งž์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ์ง์ ‘ ์†Œ์œ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ณ ,

๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ์™€ ๊ฐ™์ด ์งง์€ ์‹œ๊ฐ„๋™์•ˆ๋งŒ ๊ด€๊ณ„๊ฐ€ ์œ ์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : ์–ด๋–ค ๋„์„œ๋ฅผ ๊ณต๋ถ€ํ•œ ๋…์ž์˜ ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ

ํ•˜์ง€๋งŒ ์˜์กด์„ฑ ์ฃผ์ž…์—์„œ๋Š” ์†์„ฑ ์ฃผ์ž…์ด๋‚˜ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜์— ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฐ ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๋Š” ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ๋Š” '์—ฐ๊ด€ ๊ด€๊ณ„ (association)' ๋กœ ํ‘œํ˜„ํ•˜๊ฑฐ๋“ ์š”??

๊ทธ๋ž˜์„œ ์™œ ์—ฐ๊ด€์„ฑ ์ฃผ์ž…์ด ์•„๋‹ˆ๋ผ ์˜์กด์„ฑ ์ฃผ์ž…์ธ์ง€ ํ•œ๋™์•ˆ ๊ณ ๋ฏผํ–ˆ์—ˆ๋Š”๋ฐ,

๊ทธ๋ƒฅ ์—ฐ๊ด€์„ฑ์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ

ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์ด๋ผ๋Š” ์˜์—ญ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ๋กœํ•œ ์šฉ์–ด๋กœ ์ƒ๊ฐํ•˜๊ธฐ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

(๊ฒฐ๋ก  : ๋‚˜๋ฆ„ ํ•ด๊ฒฐํ•จ)



์™œ ์˜์กด์„ฑ ์ฃผ์ž…์ด ํ•„์š”ํ•œ๊ฐ€?


์˜์กด์„ฑ์€ ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ์œ„์—์„œ ๋ง์”€๋“œ๋ ธ๋Š”๋ฐ์š”.

๊ทธ๋Ÿฌ๋ฉด ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ์š”?

์•„๋ž˜์—์„œ๋Š” A ํด๋ž˜์Šค๊ฐ€ B ํด๋ž˜์Šค์— ์˜์กด์„ฑ์ด ์ƒ๊ธฐ๋Š” ๊ฒฝ์šฐ๋กœ ๊ฐ€์ •ํ•ด์„œ ๊ธ€์„ ์“ฐ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ์„ธ ๊ฐ€์ง€๋ฅผ ๋‚˜์—ดํ•ด๋ณด์ž๋ฉด

1. B ํด๋ž˜์Šค์˜ ์‹ฑ๊ธ€ํ†ค์„ ์ด์šฉํ•œ๋‹ค

2. ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ํ˜น์€ ์ƒ์ˆ˜๋กœ B ํด๋ž˜์Šค์˜ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค

3. ๋ฉ”์„œ๋“œ์˜ ์ „๋‹ฌ์ธ์ž๋กœ ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค

์œ„ ์„ธ๊ฐ€์ง€ ๊ฒฝ์šฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค๐Ÿ”Ž

์ด ๋•Œ, ๋‹จ์ˆœํžˆ ์˜์กด์„ฑ์ด ์ƒ๊ธฐ๋Š” ๊ฒƒ๊ณผ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ์€ ๊ตฌ๋ณ„ํ•ด์•ผ ํ•œ๋‹ค๋Š”์ ์„ ๊ธฐ์–ตํ•ด์ฃผ์„ธ์š”!


1. B ํด๋ž˜์Šค์˜ ์‹ฑ๊ธ€ํ†ค์„ ์ด์šฉํ•  ๋•Œ ์˜์กด์„ฑ์ด ์ƒ๊ธด๋‹ค.

class A { func hasDependency() -> Int { return B.default.func() // B ํด๋ž˜์Šค์˜ ์‹ฑ๊ธ€ํ†ค์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. } }

์šฐ์„  ์‹ฑ๊ธ€ํ†ค์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์˜์กด์„ฑ ์ฃผ์ž…์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๊ฐ€์žฅ ํŽธํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ ํฐ ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐ”๋กœ Testable ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
A๋ฅผ ๊ธฐ๋Šฅ์„ Test ํ•˜๋ ค๋ฉด ์ œ๋Œ€๋กœ ์ดˆ๊ธฐํ™”๋œ B๊ฐ€ ํ•„์ˆ˜์ ์œผ๋กœ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์†Œํ”„ํŠธ์›จ์–ด ๊ณตํ•™์—์„œ๋Š” ํ•ญ์ƒ ์„ค๊ณ„ํ•  ๋•Œ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ์‘์ง‘๋„๋ฅผ ๋†’์ด๋ผ๋Š” ๋ง์„ ์ž์ฃผ ๋ณด๊ฒŒ ๋˜๋Š”๋ฐ์š”.
์ด๋ ‡๋“ฏ ์‹ฑ๊ธ€ํ†ค ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์•„์ง€๊ณ , ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
:: ์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค์„ ์•ˆํ‹ฐํŒจํ„ด์ด๋ผ๊ณ  ํ‘œํ˜„ํ•˜๋Š” ๋ถ„๋“ค๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ Controversy ํ•œ Topic ์ธ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ A ํด๋ž˜์Šค๊ฐ€ ์˜์กด์„ฑ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด
A์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ํ›‘์–ด๋ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€ ๋ณด์ˆ˜๋„ ํž˜๋“ค๊ฒ ๋„ค์š”!!


2. ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ํ˜น์€ ์ƒ์ˆ˜๋กœ B ํด๋ž˜์Šค์˜ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

2๋ฒˆ ๋ฐฉ๋ฒ•์€ ๋‹ค์‹œ ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋‰  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2-1. A ํด๋ž˜์Šค๊ฐ€ B ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•œ๋‹ค

class A { private let b = B() }

A ํด๋ž˜์Šค ๊ฐ€ B ํด๋ž˜์Šค์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ A ๊ฐ€ B ์˜ ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ• ๊นŒ์ง€ ์•Œ ํ•„์š”๊ฐ€ ์žˆ์„๊นŒ์š”?
๋‹จ์ผ ์ฑ…์ž„ ์›์น™๊ณผ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ์— ์–ด๊ธ‹๋‚˜๋Š” ์„ค๊ณ„ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜์— ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.



2-2. B ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ ์ „๋‹ฌํ•ด์ค€๋‹ค

๊ทธ๋Ÿฐ๋ฐ 2-2 ๋ฐฉ๋ฒ•์—๋Š” ๋˜ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋ผ๊ณ  ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

2-2-1. ์ดˆ๊ธฐํ™” ์‹œ์ ์— ์ „๋‹ฌํ•œ๋‹ค

class A { private let b: B init(b: B) { self.b = b } }

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ดˆ๊ธฐํ™” ์‹œ์ ์— A ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ค ํด๋ž˜์Šค์— ์˜์กด์„ฑ์ด ์žˆ๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ B ํด๋ž˜์Šค ์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ์— ๊ด€์—ฌํ•˜์ง€ ์•Š์œผ๋‹ˆ, ๊ฒฐํ•ฉ๋„๊ฐ€ ์ค„์–ด๋“ค๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ SRP ์— ๋” ๋ถ€ํ•ฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ถ€๊ฐ€์ ์ธ ์žฅ์ ์œผ๋กœ๋Š” ์ดˆ๊ธฐํ™” ์‹œ์ ์— ์ „๋‹ฌํ•˜๋ฏ€๋กœ ์†์„ฑ์ด ํ•ญ์ƒ ์กด์žฌํ•จ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๊ณ ,
( ์ดˆ๊ธฐํ™” ์‹คํŒจ์‹œ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ )
๊ทธ ์ด์œ  ๋•Œ๋ฌธ์— Optional ๋กœ ๋ž˜ํ•‘ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค๋Š” ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœํ† ์ฝœ ๋‘๋‘๋‘ฅ์žฅ :


๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์— ์Šค์œ„ํ”„ํŠธ์˜ ํ”„๋กœํ† ์ฝœ ์ง€ํ–ฅ ๊ฐœ๋…์„ ์ถ”๊ฐ€ํ•˜๋ฉด, ๋” ๋ฉ‹์ง€๊ฒŒ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

protocol Bable { func test() -> Int } class A { private let b: Bable init(b: Bable) { self.b = b } }

์œ„ ์ฝ”๋“œ์—์„œ์ฒ˜๋Ÿผ ์ธ์Šคํ„ด์Šค ์ƒ์ˆ˜๋ฅผ B ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜๋Š” ๋Œ€์‹ ,
B ์—๊ฒŒ์„œ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ๋“ค๋งŒ์„ ์š”๊ตฌ์‚ฌํ•ญ์œผ๋กœ ๊ฐ–๋Š” Babel ํ”„๋กœํ† ์ฝœ ํƒ€์ž…์œผ๋กœ ๋ฐ›์œผ๋ฉด, ๊ตฌํ˜„์ด ํ›จ์”ฌ ๋” ์ž์œ ๋กœ์›Œ์ง‘๋‹ˆ๋‹ค.

์š”๊ตฌ์‚ฌํ•ญ๋งŒ ์ถฉ์กฑํ•˜๋Š” ํƒ€์ž…์ด๋ผ๋ฉด ์–ด๋–ค ํด๋ž˜์Šค๋„ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋‹ˆ๊นŒ์š”.

๋˜ํ•œ B์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด ์ œํ•œ๋œ ๊ธฐ๋Šฅ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ,
๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ ํ™•์žฅ์ด ์—†์–ด์ง‘๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ํ…Œ์ŠคํŠธ ์ธก๋ฉด์—์„œ
Bable ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•œ ์ž„์˜์˜ Mock ๊ฐ์ฒด๋กœ ๋Œ€์ฒด๊ฐ€ ์ˆ˜์›”ํ•˜๋ฏ€๋กœ Testable ํ•ด์ง‘๋‹ˆ๋‹ค.

:: ํ”„๋กœํ† ์ฝœ ์ž‘๋ช…์—์„œ ๋ณดํ†ต ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด -Type, ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด -able ์„ ์ ‘๋ฏธ์–ด๋กœ ๋ถ™์ด๋Š” ๊ฒƒ๊ฐ™์•„์„œ B-able ๋กœ ์ž‘๋ช…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


2-2-2 ์ดˆ๊ธฐํ™” ์ดํ›„, A ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ์†์„ฑ์— ์ ‘๊ทผํ•˜์—ฌ ์ „๋‹ฌํ•œ๋‹ค.

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let vc = segue.destination else { return } /* ์ธ์Šคํ„ด์Šค vc ์˜ ์†์„ฑ b ์— B ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž… */ vc.b = B() }

iOS ๊ฐœ๋ฐœ์—์„œ๋Š” 2-2-2 ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ์˜์กด์„ฑ ์ฃผ์ž…์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค

๋ฐ”๋กœ Storyboard, xib ๋กœ ์•ฑ UI ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ์ธ๋ฐ์š”.

Storyboard ๋กœ ์•ฑ UI ๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด, ์ปค์Šคํ…€ ์ด๋‹ˆ์…œ๋ผ์ด์ €๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด UI ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ํ•„์—ฐ์ ์œผ๋กœ UIKit ์˜ UIView ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ,
์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ์˜์กด์„ฑ ์ฃผ์ž…( ๋ฐฉ๋ฒ• 2-2-1) ์„ ์œ„ํ•ด ์ปค์Šคํ…€ ์ด๋‹ˆ์…œ๋ผ์ด์ €๋ฅผ ๋งŒ๋“ค๊ฒฝ์šฐ
required init(coder:) ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ( ์ˆ˜ํผ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ์ž๋™ ์ƒ์†์ด ์ทจ์†Œ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.)
:: ์ด ๋ถ€๋ถ„์€ NSCoding, Swift ์˜ ์ƒ์†, Protocol ๊ฐœ๋…์„ ์ œ๋Œ€๋กœ ์•Œ๊ณ  ์žˆ์–ด์•ผ ์ดํ•ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

init(coder:) ๋Š” Xcode ๊ฐ€ Storyboard ๋‚˜ xib ํŒŒ์ผ์„ ์–ธ์•„์นด์ด๋น™ํ• ๋•Œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š” ์ƒ์„ฑ์ž์ž…๋‹ˆ๋‹ค.
์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ดˆ๊ธฐํ™” ์‹œ์  ์ดํ›„์— ์†์„ฑ์„ ๋„ฃ์–ด์ฃผ์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์†์„ฑ ํƒ€์ž…์„ ์˜ต์…”๋„๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ฐ™์€ ์ด์œ ๋กœ ์ƒ์ˆ˜๊ฐ€ ์•„๋‹Œ ๋ณ€์ˆ˜๋กœ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ ์ด ๋ฐฉ๋ฒ•์€ Storyboard ๋ฐฉ์‹์œผ๋กœ UI๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ, ์˜์กด์„ฑ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.


init(coder:) ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด? ๐Ÿ‘‰๐Ÿป [iOS] init(coder:) ๋ž€?
์•„์นด์ด๋น™, ์–ธ์•„์นด์ด๋น™์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด? ๐Ÿ‘‰๐Ÿป[iOS] NSCoding ์ด๋ž€? (feat. ์ธ์ฝ”๋”ฉ, ๋””์ฝ”๋”ฉ, ์•„์นด์ด๋น™)


3. ๋ฉ”์„œ๋“œ์˜ ์ „๋‹ฌ์ธ์ž๋กœ ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค.

class A { var someValue: Int func useB(b: B) { self.someValue = b.getValue() } } let a = A() let b = B() a.useB(b: b)

์ด ๋ฐฉ๋ฒ•์˜ ๊ฒฝ์šฐ
๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ๋งŒ ์ผ์‹œ์ ์œผ๋กœ ์˜์กด๊ด€๊ณ„๊ฐ€ ์ƒ๊ธฐ๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.


๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๋ฌด์—‡์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š”๊ฐ€


์ด ๊ฒฐ๋ก ์— ๋„๋‹ฌํ•˜๋ ค๊ณ  ์ •๋ง ๊ธธ๊ฒŒ๋„ ๊ธ€์„ ์ผ๋„ค์š”...ใ…Žใ…Žใ…Žใ…Ž

์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ ์šฐ๋ฆฌ๋Š”:


์ฑ…์ž„์ด ์ข€ ๋” ๋ช…ํ™•ํ•ด์ง„ ํด๋ž˜์Šค๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์–ด๋–ค ์˜์กด ๊ด€๊ณ„์™€ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋Š”์ง€ ์ˆ˜์›”ํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Testable ํ•œ ํด๋ž˜์Šค๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Protocol type์œผ๋กœ ๋ฐ›์„ ์‹œ ์‰ฝ๊ฒŒ Mock ์˜ค๋ธŒ์ ํŠธ๋กœ ๋Œ€์ฒดํ• ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ ์›์น™์„ ์ž˜ ์ง€ํ‚ฌ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋” ์ด์ƒ ์˜์กด ๊ด€๊ณ„์˜ ๊ฐ์ฒด์˜ ์ดˆ๊ธฐํ™”์— ์ง์ ‘ ๊ด€์—ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•œ ์˜์กด์„ฑ ์ฃผ์ž…์€ ๊ฒฐํ•ฉ๋„๋ฅผ ์ค„์ด๊ณ , ์ฃผ์ž…๋œ ๊ฐ์ฒด์˜ ์ฑ…์ž„์„ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋์œผ๋กœ ์–ด๋””์„œ ์ฃผ์›Œ๋“ค์€ ๋ฉ‹์ง„ ๋ฌธ์žฅ ๋งํ•˜๊ณ  ์ €๋Š” ๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค!๐Ÿƒ๐Ÿปโ€โ™€๏ธ

Do not depend on Concretion.

Depend on Abstraction.


์˜ค๋Š˜๋„ ๋‚˜๋Š” ์„ฑ์žฅํ–ˆ๋‹ค!!!!โœŠ๐Ÿป


๐Ÿค–๐ŸŸข[์šฐ์งฑ์˜ iOS ๋ธ”๋กœ๊ทธ]๐Ÿ”ต๐Ÿ’ป

iOS๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๊ธฐ๋กํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ
https://www.youtube.com/watch?v=-n8allUvhw8
https://www.youtube.com/watch?v=sHLd1BuW0aU&t=2s
https://daniel-sumara.medium.com/removing-singletons-4340c6f6398a