Post

๐Ÿคฉ ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜

๊ฐœ์š”

Robert C. Martin์˜ Clean Architecture๋ฅผ ์ฝ๊ณ , ๋‚˜๋ฆ„์˜ ์ดํ•ด๋ฅผ ์œ„ํ•œ ๋…ธ๋ ฅ๊ณผ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์—๋Š” ์–ด๋–ป๊ฒŒ ์ ์šฉํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์— ๋Œ€ํ•ด ํฌ์ŠคํŒ…ํ•˜๋ ค ํ•œ๋‹ค.

(์ •๋ฆฌ์™€ ๋ณ„๊ฐœ๋กœ ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ์ด ๋“ค์–ด์žˆ์–ด ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)
(๋‹ค๋ฅธ ์ ์— ๋Œ€ํ•ด์„œ๋Š” ์˜๊ฒฌ์„ ๊ณต์œ ํ•ด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค!!)

The Clean Architecture ํฌ์ŠคํŠธ

ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

ํ•„์š”ํ•œ ๋ถ€๋ถ„ (Infra)๋งŒ ๋ฐ”๊ฟ”๋„ ํ”„๋กœ์ ํŠธ ์ƒ์— ๋ฌธ์ œ๊ฐ€ ์•ˆ๋œ๋‹ค.

  • ์†Œ์Šค ์ฝ”๋“œ ์•ˆ์ •์„ฑ โ†‘
  • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ โ†‘
  • ์œ ์ง€ ๋ณด์ˆ˜์„ฑ โ†‘

๋‹ค๋งŒ, ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ธ‰ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ์ฒœ์ฒœํžˆ ์„ค๊ณ„๋ฅผ ํ•ด๋‚˜๊ฐ€๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค ์ž˜ ์ง€ํ‚ค๊ธฐ ์–ด๋ ต๋‹ค.

๋‚ด์šฉ

๐Ÿ’ก ์•„ํ‚คํ…์ฒ˜์˜ ์ œ์•ฝ ์กฐ๊ฑด

ํฌ์ŠคํŠธ์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์•„ํ‚คํ…์ฒ˜(Hexagonal, Onion ๋“ฑโ€ฆ)๋Š” ์„ธ๋ถ€์‚ฌํ•ญ(๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง)์€ ๋‹ฌ๋ผ๋„ ๊ณตํ†ต์˜ ๋ชฉํ‘œ๋Š” ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํ•œ๋‹ค.


์œ„ ์ด๋ฏธ์ง€์—์„œ ๋ฐ”๊นฅ์ชฝ ์›์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„, ๋‚ด๋ถ€ ์›์€ ์ •์ฑ…์„ ์˜๋ฏธํ•œ๋‹ค.
๋ฐ”๊นฅ-> ์•ˆ์œผ๋กœ ๊ฐˆ์ˆ˜๋ก ๊ณ ์ˆ˜์ค€์˜ ์†Œํ”„ํŠธ์›จ์–ด๊ฐ€ ๋œ๋‹ค.


์ด๋Ÿฌํ•œ ์•„ํ‚คํ…์ฒ˜๋“ค์˜ ์ œ์•ฝ์กฐ๊ฑด์€ ๋‹ค์Œ์œผ๋กœ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ํ”„๋ ˆ์ž„์›Œํฌ์— ๋ฌด๊ด€ํ•˜๋‹ค.
    • ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  2. ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์€ UI, DB๋“ฑ ์™ธ๋ถ€์š”์†Œ ์—†์ด ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค.
  3. UI์™€ ๋ฌด๊ด€ํ•ด์•ผ ํ•œ๋‹ค.
  4. DB์— ๋…๋ฆฝ์ ์ด์–ด์•ผ ํ•œ๋‹ค.(Mysql, Oracleโ€ฆ)
  5. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์™ธ๋ถ€ ์š”์†Œ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋™์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” (== ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”) ์˜์กด์„ฑ ๊ทœ์น™ ์„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค.

๐Ÿ’ก ์˜์กด์„ฑ ๊ทœ์น™

์˜์กด์„ฑ ๊ทœ์น™์€ ๋ชจ๋“  ์†Œ์Šค์ฝ”๋“œ ์˜์กด์„ฑ์€ ์™ธ๋ถ€ -> ๋‚ด๋ถ€ ์ฆ‰, ๊ณ ์ˆ˜์ค€์˜ ์ •์ฑ…์„ ํ–ฅํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ณ ์ˆ˜์ค€ : ์ถ”์ƒํ™”๋œ ๊ฐœ๋…

  • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • ์ด ๊ทผ๋ฌด ์‹œ๊ฐ„์„ ๊ตฌํ•œ๋‹ค.

์ €์ˆ˜์ค€ : ์„ธ๋ถ€ํ™”๋œ ๊ฐœ๋…

  • mysql์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ๋‹ค.
  • A์‚ฌ์šฉ์ž์˜ ๊ทผ๋ฌด์‹œ๊ฐ„์„ ๋‹ค ๋”ํ•œ๋‹ค.


์œ„์˜ ๊ทธ๋ฆผ์—์„œ Domain Layer๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์กด์žฌํ•˜๋Š” ์˜์—ญ์ด๋‹ค. (๊ณ„์‚ฐ๊ธฐ๋Š” ๊ณ„์‚ฐ์„, ์‡ผํ•‘๋ชฐ์€ ๋ฌผ๊ฑด์˜ ํŒ๋งค๋ฅผ)

๋น„์ฆˆ๋‹ˆ์Šค์˜ ๋ณธ์งˆ์€ ์‰ฝ๊ฒŒ ๋ฐ”๋€Œ์ง€ ์•Š์œผ๋ฏ€๋กœ ์ž˜ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ์˜์—ญ์ด๋‹ค.

Infra Layer๋Š” UI, Framework ๋“ฑ์ด ์กด์žฌํ•˜๋Š” ์˜์—ญ์ด๋‹ค.
Infra๋Š” ์ž์ฃผ ๋ฐ”๋€Œ์–ด๋„ ๋‚ด๋ถ€ ๋กœ์ง์€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค. (๊ณ„์‚ฐ ๋ฒ„ํŠผ์˜ ์ƒ‰์€ ๋ฐ”๋€Œ์–ด๋„ ๊ณ„์‚ฐ๊ธฐ์˜ ๊ณ„์‚ฐ์ด ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค.)
๊ณ ์ˆ˜์ค€ ์ •์ฑ…์ธ Domain์€ ์ €์ˆ˜์ค€ ์ •์ฑ…์ธ Infra์— ๋Œ€ํ•ด ์•„๋ฌด๊ฒƒ๋„ ๋ชฐ๋ผ๋„ ๋œ๋‹ค.
์ด๋ ‡๊ฒŒ Layer๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ Infrastructure๋ฅผ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.



Martin์˜ ์•„ํ‚คํ…์ฒ˜๋Š” 4๊ฐœ์˜ ๋ ˆ์ด์–ด๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค.

Entities

์ „์‚ฌ์  ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ๋‹ด๋Š”๋‹ค.
์ด๋Š” ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ ๋‚ด์˜ ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋  . ์ˆ˜์žˆ๋‹ค.(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ข…์†X)

๊ฒŒ์ž„์œผ๋กœ ์น˜๋ฉด ๋ชฌ์Šคํ„ฐ, ์•„์ดํ…œ ๋“ฑ์˜ ์ƒ์„ธ ์ •๋ณด ์ถœ์ž…ํ†ต์ œ๋กœ ์น˜๋ฉด ๋‹จ๋ง๊ธฐ, ์œ ์ €, ๋ฌธ์˜ ์ƒ์„ธ ์ •๋ณด ์—…๋ฌด ๋ณด๊ณ  ์„œ๋น„์Šค๋กœ ์น˜๋ฉด ์—…๋ฌด ๋ณด๊ณ ์„œ

(๋ฐ”๋€Œ์ง€ ์•Š๋Š” ๋ถ€๋ถ„์ด๋ผ ํ•˜์ง€๋งŒ, ์‚ฌ์‹ค ๋‚ด๋ถ€ ์‚ฌ์ •์— ์˜ํ•ด ๋งŽ์ด ๋ฐ”๋€๋‹คโ€ฆ๐Ÿ˜ญ)

Use Cases

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ณ„ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ๋‹ด๋Š”๋‹ค.
์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ†ตํ•ด ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๊ฒŒ์ž„

  • ๋ชฌ์Šคํ„ฐ๋ฅผ ์‚ฌ๋ƒฅํ•œ๋‹ค.
  • ์•„์ดํ…œ์„ ์žฅ์ฐฉํ•œ๋‹ค.

์ถœ์ž…ํ†ต์ œ

  • ๋‹จ๋ง๊ธฐ์— ์ธ์ฆํ•œ๋‹ค.
  • ๋‹จ๋ง๊ธฐ๋ฅผ ์ œ์–ดํ•˜์—ฌ ๋ฌธ์„ ์—ฐ๋‹ค.

์—…๋ฌด ๋ณด๊ณ  ์„œ๋น„์Šค

  • ์ผ์ผ ์—…๋ฌด๋ณด๊ณ ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
  • ์—…๋ฌด ๋ณด๊ณ ๋ฅผ ์กฐํšŒํ•œ๋‹ค.
  • ์ฃผ๊ฐ„ ๋ณด๊ณ ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

Interface Adapter

์–ด๋Œ‘ํ„ฐ ๊ณ„์ธต์€ Infra ์ธก์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๋„๋ก Use Case ํ˜น์€ Entities์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณ„์ธต์ด๋‹ค.
๋ณดํ†ต MVC, MVVM์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ํฌํ•จํ•˜๋Š” ์˜์—ญ์œผ๋กœ Controller, Presenter ๋“ฑ์ด ์†ํ•œ๋‹ค.

Framework && Driver

Infra ๊ณ„์ธต์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค.
DB, Framework ๋ฅผ ํฌํ•จํ•œ๋‹ค. ๋ณดํ†ต ๋‚ด๋ถ€์— ๋น„ํ•ด ๋ณ€ํ™”๊ฐ€ ์žฆ๋‹ค.


๐Ÿ’ก ์˜์กด์„ฑ ๊ทœ์น™์„ ์ง€ํ‚ค๋Š” ๋ฐฉ๋ฒ•

What data crosses the boundaries

๊ฒฝ๊ณ„๊ฐ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ๋ฌด์—‡์„ ์ „๋‹ฌํ•ด์•ผํ•˜๋Š”๊ฐ€์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋‹ค.
์˜์กด์„ฑ์„ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ตœ๋Œ€ํ•œ ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜์—ฌ ๊ฐ ์‹œ์Šคํ…œ์ด ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

Crossing boundaries

์‹ค์ œ ์‹œ์Šคํ…œ์˜ ํ๋ฆ„์€ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ -> ์‘๋‹ต์ด๋‹ค.
์ด ํ๋ฆ„์€ ์›์—์„œ ์™ธ๋ถ€ -> ๋‚ด๋ถ€ -> ์™ธ๋ถ€์ธ๋ฐ, ์ด๋Š” ์•„ํ‚คํ…์ฒ˜์˜ ์˜์กด์„ฑ ๊ทœ์น™์— ์œ„๋ฐฐ๋œ๋‹ค.
์ด ๋ถ€๋ถ„์ด ๋งŽ์ด ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„์ด์—ˆ๋‹ค.
์•„ํ‚คํ…์ฒ˜์˜ ๋™์‹ฌ์›์—์„œ๋Š” repository๊ฐ€ ๋” ๋ฐ”๊นฅ๋ถ€๋ถ„์ด์ง€๋งŒ, ์‹ค์ œ ํ๋ฆ„์—์„œ๋Š” usecase๊ฐ€ ๋” ๋ฐ”๊นฅ๋ถ€๋ถ„์ธ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ๋•Œ๋ฌธ์ด๋‹ค.
๋”ฐ๋ผ์„œ, usecase๊ฐ€ repository๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๊ฑด ์˜์กด์„ฑ ๊ทœ์น™์— ์œ„๋ฐฐ๋˜๊ณ  ์ด๋ฅผ DIP๋ฅผ ํ†ตํ•ด์„œ ํ•ด๊ฒฐํ•ด์•ผํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋‹ค.

๐Ÿ‘‰ Conclusion

์†Œํ”„ํŠธ์›จ์–ด์˜ ์ผ์ƒ ์ฃผ๊ธฐ์—์„œ ๊ฐ€์žฅ ๋น„์šฉ์ด ๋งŽ์ด๋“œ๋Š” ์ฃผ๊ธฐ๋Š” ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ด๋ฃจ์–ด์ง€๋Š” ๋‹จ๊ณ„์ด๋‹ค. ์ž˜ ๊ตฌ์กฐํ™”๋˜๊ณ  ์ถ”์ƒํ™”๋œ ์†Œํ”„ํŠธ์›จ์–ด ์‹œ์Šคํ…œ์€ ์œ ์ง€๋ณด์ˆ˜ ํ•˜๊ธฐ ์‰ฝ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž์˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ฐ›์•„๋“ค์ด๊ธฐ ์‰ฌ์›Œ ์ƒˆ๋กœ์šด ๊ฐ€์น˜๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๊ธฐ ์‰ฝ๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

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

This post is licensed under CC BY 4.0 by the author.