DDD start! ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ ๊ตฌํ๊ณผ ํต์ฌ ๊ฐ๋ ์ตํ๊ธฐ๋ฅผ ์ฝ์ผ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ ์ ๋๋ค.
DDD๋ ๋ฌด์์ผ๊น?
๋น์ฆ๋์ค ๋๋ฉ์ธ๋ณ๋ก ๊ณตํต์ฉ์ด(Ubiquitous Language)๋ฅผ ์ฌ์ฉํ๋ฉฐ ๋๋ฉ์ธ์ ํ๋ก์ธ์ค/์ ์ฑ ๋ณ๋ก Context๋ฅผ ๋๋๊ณ , ์ด๋ฌํ Bounded Context๋ฅผ Context Map์ผ๋ก ๋์ํ๋ฅผ ํ๋ ์ ๋ต์ค๊ณ์ Presentation, Service, Domain, Infrastructure ๊ณ์ธต ๊ตฌ์กฐ๋ก ์ค๊ณ๋ฅผ ํ์ฌ ์ดํ๋ฆฌ์ผ์ด์ ๊ฐ์ ์์กด์ฑ์ ์ต์ํ ํ๊ณ ์์ง๋๋ฅผ ์ต๋ํ ํ๋๊ฒ์ด๋ค.
- ํ๋์ ๋๋ฉ์ธ์ ํ์์ ์ฌ๋ฌ ๋๋ฉ์ธ์ผ๋ก ๋๋ ์ ์๋ค.
- ๋๋ฉ์ธ ๋ง๋ค ๊ณ ์ ๋ ํ์ ๋๋ฉ์ธ์ด ์กด์ฌํ๋ ๊ฒ์ ์๋๋ค.
- ๋๋ฉ์ธ์ ์ด๋ป๊ฒ ๊ตฌ์ฑํ ์ง ์ฌ๋ถ๋ ์ํฉ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๋๋ฉ์ธ ๋ชจ๋ธ์ ํน์ ๋๋ฉ์ธ์ ๊ฐ๋ ์ ์ผ๋ก ํํ ํ ๊ฒ. ์ฆ, ๋๋ฉ์ธ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๊ด๊ณ์๋ค์ด ๋์ผํ ๋ชจ์ต์ผ๋ก ๋๋ฉ์ธ์ ์ดํดํ๊ณ ๋๋ฉ์ธ ์ง์์ ๊ณต์ ํ๋๋ฐ ๋์์ด ๋๋ค.
๋๋ฉ์ธ ๋ชจ๋ธ ํํ ๋ฐฉ์
- ๊ฐ์ฒด ๊ธฐ๋ฐ ์ฃผ๋ฌธ ๋๋ฉ์ธ ๋ชจ๋ธ๋ง (์ฃผ์ ๋ฐ์ดํฐ ๊ตฌ์ฑ์ ํ์ ํ๊ณ ๊ธฐ๋ฅ๊ณผ ๋ฐ์ดํฐ ๋ณด์ฌ์ฃผ๊ธฐ ์ ํฉ)
- ํด๋์ค ๋ค์ด์ด๊ทธ๋จ, ์ํ ๋ค์ด์ด๊ทธ๋จ์ ์ด์ฉํ ์ํ ๋ชจ๋ธ๋ง
- ์ด์ธ์๋ ๊ทธ๋ํ ์ด์ฉํ ๋ชจ๋ธ๋ง ๋ฑ
๊ณ์ธต(Layer) | ์ค๋ช |
---|---|
์ฌ์ฉ์์ธํฐํ์ด์ค(UI) ๋๋ ํํ(Presentation) | ์ฌ์ฉ์์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค๋ค.(Controller) |
์์ฉ(Application | ์ฌ์ฉ์๊ฐ ์์ฒญํ ๊ธฐ๋ฅ์ ์คํ / ์ ๋ฌด ๋ก์ง์ ์ง์ ๊ตฌํํ์ง ์์ผ๋ฉฐ ๋๋ฉ์ธ ๊ณ์ธต์ ์กฐํฉํด ๊ธฐ๋ฅ์ ์คํ |
๋๋ฉ์ธ | ์์คํ ์ด ์ ๊ณตํ ๋๋ฉ์ด๋์ด ๊ท์น์ ๊ตฌํ (Aggregate, Entity) |
์ธํ๋ผ์คํธ๋ญ์ฒ(Infrastructure) | ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฉ์ธ์ง ์์คํ ๊ณผ ๊ฐ์ ์ธ๋ถ ์์คํ ๊ณผ์ ์ฐ๋ ์ฒ๋ฆฌ(DB ์ฐ๋, Message Queue, SMTP Email, External API) |
- ๋๋ฉ์ธ ๋ชจ๋ธ ํจํด
- ํด๋น ๋๋ฉ์ธ์ ๊ท์น์ ๊ตฌํํ ์ฝ๋๊ฐ ๋๋ฉ์ธ ๊ณ์ธต์ ์์นํ๊ณ , ์ด๋ฐ ๋๋ฉ์ธ ๊ท์น์ ๊ฐ์ฒด ์งํฅ ๊ธฐ๋ฒ์ผ๋ก ๊ตฌํํ๋ ํจํด (์๋น์ค ๊ณ์ธต์ ๋จ์ํ ์ํฐํฐ์ ํ์ํ ์์ฒญ์ ์์ํ๋ ์ญํ )
- ํต์ฌ ๊ท์น์ ๊ตฌํํ ์ฝ๋๋ ๋๋ฉ์ธ ๋ชจ๋ธ์๋ง ์์นํ๋ฏ๋ก, ๊ท์น์ด ๋ฐ๋๊ฑฐ๋ ํ์ฅํด์ผํ ๋ ๋ค๋ฅธ ์ฝ๋์ ์ํฅ์ ๋ ์ฃผ๊ณ ๋ณ๊ฒฝ ๋ด์ญ์ ๋ชจ๋ธ์ ๋ฐ์ํ ์ ์๋ค.
cf. ํธ๋์ญ์ ์คํฌ๋ฆฝํธ ํจํด
์ํฐํฐ์๋ ๋น์ฆ๋์ค ๋ก์ง์ด ๊ฑฐ์ ์๊ณ ์๋น์ค ๊ณ์ธต์์ ๋๋ถ๋ถ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ๊ฒ.
๊ธฐํ์, ์ ์ค ์ผ์ด์ค, ์ฌ์ฉ์ ์คํ ๋ฆฌ์ ๊ฐ์ ์๊ตฌ ์ฌํญ๊ณผ ๊ด๋ จ์๋ค์ ๋ํ๋ฅผ ํตํด ๋๋ฉ์ธ์ ์ดํดํ๋ ๊ฒ์ด ์ฒซ ์์!
๋๋ฉ์ธ ๋ชจ๋ธ๋ง ๋ ๋ชจ๋ธ์ ๊ตฌ์ฑํ๋ ํต์ฌ ๊ตฌ์ฑ์์
, ๊ท์น
, ๊ธฐ๋ฅ
์ ์ฐพ์์ผ ํ๋ค.
๋๋ฉ์ธ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ค๊ณํ๊ณ ๊ตฌํํ๊ธฐ ์ํด์๋ ์ํฐํฐ์ ๋ฐธ๋ฅ์ ์ฐจ์ด๋ฅผ ๋ช ํํ๊ฒ ์ดํดํ๊ณ ์ ๋๋ก ๊ตฌ๋ถํ๋ ๊ฒ์ด ๋๋ฉ์ธ์ ๊ตฌํํ๋๋ฐ ์์ด ์ค์!
์๋ณ์๋ฅผ ๊ฐ๋๋ค. (๊ฐ ์ํฐํฐ๋ ์๋ก ๋ค๋ฅธ ์๋ณ์๋ฅผ ๊ฐ๋๋ค. ex. ์ฃผ๋ฌธ์ ๊ฐ ์ฃผ๋ฌธ๋ง๋ค ์ฃผ๋ฌธ๋ฒํธ๊ฐ ๋ค๋ฅด๋ฉฐ ์ฃผ๋ฌธ๋ฒํธ
๊ฐ ์๋ณ์๊ฐ ๋จ)
์๋ณ์ ์์ฑ์ ์ฌ์ฉ ๊ธฐ์ ๊ณผ ํน์ง์ ๋ฐ๋ผ ๋ค๋ฅด๋ ํํ ์๋์ ๊ฐ์ ๋ฐฉ์์ ์ฌ์ฉํ๋ค. (โ ๊ฐ์ ์๊ฐ์ ๋์์ ์๋ณ์๋ฅผ ์์ฑํ ๋ ๊ฐ์ ์๋ณ์๊ฐ ๋ง๋ค์ด์ง๋ฉด ์๋๋ค.)
- ํน์ ๊ท์น์ ๋ฐ๋ผ ์์ฑ
- UUID ์ฌ์ฉ
- ๊ฐ์ ์ง์ ์ ๋ ฅ
- ์ผ๋ จ๋ฒํธ ์ฌ์ฉ(Oracle ์ํ์ค๋ MySQL ์๋ ์ฆ๊ฐ ์ปฌ๋ผ ์ฌ์ฉ)
๊ฐ๋ ์ ์ผ๋ก ์์ ํ ํ๋๋ฅผ ํํํ ๋ ์ฌ์ฉ (ex. ์ฃผ์ = address1, address2, zipCode)
์ฅ์ )
- ์ฝ๋์ ์๋ฏธ๋ฅผ ๋ ์ ์ดํดํ ์ ์๋๋ก ํ๋ค. (๊ฐ๋ ์ ์ผ๋ก ํํ๋ ๊ฒ์ ์ฌ์ฉํด ์๋ฏธ๋ฅผ ํ์ ํ๊ธฐ ์ฌ์)
- ๋ฐธ๋ฅ ํ์ ์ ์ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ค.
๋ฐธ๋ฅ ๊ฐ์ฒด์ ๋ฐ์ดํฐ ๋ณ๊ฒฝํ ๋ ๊ธฐ์กด ๋ฐ์ดํฐ ๋ณ๊ฒฝ ๋ณด๋ค ๋ณ๊ฒฝํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ ์๋ก์ด ๋ฐธ๋ฅ ๊ฐ์ฒด ์์ฑ ๋ฐฉ์ ์ ํธ.
๋ถ๋ณ ๊ฐ์ฒด (๋ฐ์ดํฐ ๋ณ๊ฒฝ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง ์๋ ํ์
)
๋ก ๊ตฌํํ๊ฒ ๋๋ฉด ๋ณด๋ค ์์ ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
๋ถ๋ณ ๊ฐ์ฒด๋ ์ฐธ์กฐ ํฌ๋ช ์ฑ๊ณผ ์ค๋ ๋์ ์์ ํ๋ค.
set ๋ฉ์๋๋ ๋๋ฉ์ธ์ ํต์ฌ ๊ฐ๋ ์ด๋ ์๋๋ฅผ ์ฝ๋์์ ์ฌ๋ผ์ง๊ฒ ํ๋ค. ๋ํ, ๋๋ฉ์ธ ๊ฐ์ฒด ์์ฑ ์ ์์ ํ ์ํ๊ฐ ์๋ ์๋ ์๋ค. ๋๋ฉ์ธ ๊ฐ์ฒด๊ฐ ๋ถ์์ ํ ์ํ๋ก ์ฌ์ฉ๋๋ ๊ฒ ๋ฐฉ์ง ํ๋ ค๋ฉด ์์ฑ์๋ฅผ ํตํด ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ๋ฐ์์ผ ํ๋ค.
Application(service) -> Domain(entity) -> Infrastructure(DB, rule Engine, messaging)
Application(service) -> Infrastructure(DB, rule Engine, messaging)
Domain(entity) -> Infrastructure(DB, rule Engine, messaging)
- ํน์ฑ์ ์์ ๊ณ์ธต์์ ํ์ ๊ณ์ธต์ผ๋ก์ ์์กด๋ง ์กด์ฌ, ํ์ ๊ณ์ธต์ ์์ ๊ณ์ธต์ ์์กดํ์ง ์๋๋ค.
- ํ์ง๋ง, ๊ตฌํ์ ํธ๋ฆฌํจ์ ์ํด ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ์ ์ฐํ๊ฒ ์ ์ฉํ๋ค. (ex. ์์ฉ ๊ณ์ธต์ ๋๋ฉ์ธ ๊ณ์ธต์ ์์กดํ์ง๋ง ์ธ๋ถ ์์คํ ๊ณผ์ ์ฐ๋์ ์ํด ๋ ์๋ ๊ณ์ธต์ธ ์ธํ๋ผ์คํธ๋ญ์ฒ ๊ณ์ธต์ ์์กดํ๊ธฐ๋ ํจ.)
โ
์ธํ๋ผ์คํธ๋ญ์ฒ์ ์์กดํ๋ฉด, ํ
์คํธ์ ์ด๋ ค์
๊ณผ ๊ธฐ๋ฅ ํ์ฅ์ ์ด๋ ค์
์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋ ๋ค๋ฉด.. ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น?
ํด๊ฒฐ ๋ฐฉ๋ฒ์? DIP ์ ์ฉํ๋ ๊ฒ
DIP (Dependency Inversion Principle) : ์์กด์ฑ ์ญ์ ์ ๋ฒ์น ์์ ๊ณ์ธต์ด ํ์ ๊ณ์ธต์ ์์กดํ๋ ์์กด ๊ด๊ณ๋ฅผ ์ญ์ (๋ฐ์ ) ์ํด์ผ๋ก์จ ์์ ๊ณ์ธต์ด ํ์ ๊ณ์ธต์ ๊ตฌํ์ผ๋ก ๋ถํฐ ๋ ๋ฆฝ๋๊ฒ ํ ์ ์๋ค. ์ถ์ํ ํ์ฌ ๊ด๊ณ๋ฅผ ๋์จํ๊ฒ ๋ง๋ค๊ณ ํ์ฅ์ ์ ์ฐํ๊ฒ ๋ง๋ ๋ค.
ex. DIP๋ฅผ ๊ตฌํํ๋ ๊ธฐ๋ฒ ์ค ํ๋๊ฐ
DI (Dependency Injection)
์ด๋ค.
-
DIP๋ ๊ณ ์์ค ๋ชจ๋์ ๋ ์ด์ ์ ์์ค ๋ชจ๋์ ์์กดํ์ง ์๊ณ ๊ตฌํ์ ์ถ์ํํ ์ธํฐํ์ด์ค์ ์์กดํ๋ค.
-
์ค์ ์ฌ์ฉํ ์ ์์ค ๊ตฌํ ๊ฐ์ฒด๋ ์์กด ์ฃผ์ ์ ์ด์ฉํด์ ์ ๋ฌ ๋ฐ์ ์ ์๋ค.
-
DIP ์ ์ฉํ ๋ ์ค์ํ ์ !!
- ํ์ ๊ธฐ๋ฅ์ ์ถ์ํํ ์ธํฐํ์ด์ค๋ ๊ณ ์์ค ๋ชจ๋ ๊ด์ ์์ ๋์ถํ๋ค. (์ถ์ํํ ์ธํฐํ์ด์ค๊ฐ ๊ณ ์์ค ๋ชจ๋์ ์์น)
- ๋๋ฉ์ธ ์์ญ์ ๋ชจ๋ธ์ ๋๋ฉ์ธ์ ์ฃผ์ ๊ฐ๋ ์ ํํํ๋ฉฐ ํต์ฌ์ด ๋๋ ๋ก์ง์ ๊ตฌํํ๋ค.
์์ | ์ค๋ช |
---|---|
์ํฐํฐ (Entity) | ๊ณ ์ ์ ์๋ณ์๋ฅผ ๊ฐ๋ ๊ฐ์ฒด๋ก ์์ ์ ๋ผ์ดํ ์ฌ์ดํด์ ๊ฐ๋๋ค. ๋๋ฉ์ธ ๋ชจ๋ธ์ ํ ์ดํฐ๋ฅผ ํฌํจํ๋ฉฐ ํด๋น ๋ฐ์ดํฐ์ ๊ด๋ จ๋ ๊ธฐ๋ฅ์ ํจ๊ป ์ ๊ณต (ํ์, ์ํ ๊ฐใ ๋ฅธ ๋๋ฉ์ธ์ ๊ณ ์ ํ ๊ฐ๋ ํํ) |
๋ฐธ๋ฅ (Value) | ๊ณ ์ ์ ์๋ณ์๋ฅผ ๊ฐ์ง ์๋ ๊ฐ์ฒด, ๊ฐ๋ ์ ์ผ๋ก ํ๋์ธ ๋๋ฉ์ธ ๊ฐ์ฒด์ ์์ฑ์ ํํํ ๋ ์ฌ์ฉ. (์ฃผ์, ๊ตฌ๋งค ๊ธ์ก์ ์ํ ๊ธ์ก(Money) ๊ฐ์ ํ์ ) |
์ ๊ทธ๋ฆฌ๊ฑฐํธ (Aggregate) | ๊ด๋ จ๋ ์ํฐํฐ์ ๋ฐธ๋ฅ ๊ฐ์ฒด๋ฅผ ๊ฐ๋
์ ์ผ๋ก ํ๋๋ก ๋ฌถ์ ๊ฒ. (์ฃผ๋ฌธ ๊ด๋ จ๋ Order ์ํฐํฐ, OrderLine ๋ฐธ๋ฅ, Orderer ๋ฐธ๋ฅ ๊ฐ์ฒด => ์ฃผ๋ฌธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ) |
๋ ํ์งํ ๋ฆฌ (Repository) | ๋๋ฉ์ธ ๋ชจ๋ธ์ ์์์ฑ์ ์ฒ๋ฆฌ. (DBMS ํ ์ด๋ธ์์ ์ํฐํฐ ๊ฐ์ฒด๋ฅผ ๋ก๋ฉํ๊ฑฐ๋ ์ ์ฅํ๋ ๊ธฐ๋ฅ ์ ๊ณต) |
๋๋ฉ์ธ ์๋น์ค (Domain Service) | ํน์ ์ํฐํฐ์ ์ํ์ง ์๋ ๋๋ฉ์ธ ๋ก์ง ์ ๊ณต. ๋๋ฉ์ธ ๋ก์ง์ด ์ฌ๋ฌ ์ํฐํฐ์ ๋ฐธ๋ฅ๋ฅผ ํ์๋ก ํ ๊ฒฝ์ฐ ๋๋ฉ์ธ ์๋น์ค์์ ๋ก์ง์ ๊ตฌํํ๋ค. (ex. ํ ์ธ ๊ธ์ก ๊ณ์ฐ ์ฟ ํฐ, ํ์ ๋ฑ๊ธ, ๊ตฌ๋งค ๊ธ์ก ๋ฑ ๋ค์ํ ์กฐ๊ฑด์ ์ด์ฉํด์ ๊ตฌํํด์ผ ํ ๊ฒฝ์ฐ) |
- ์ฐจ์ด์
- ๋๋ฉ์ธ ๋ชจ๋ธ์ ์ํฐํฐ: ๋ฐ์ดํฐ์ ํจ๊ป ๋๋ฉ์ธ ๊ธฐ๋ฅ์ ํจ๊ป ์ ๊ณตํ๋ ๊ฐ์ฒด
- ๋๋ฉ์ธ ๊ด์ ์์ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ณ ๊ธฐ๋ฅ ๊ตฌํ์
์บก์ํ
ํด์ ์์๋ก ๋ณ๊ฒฝ๋๋ ๊ฒ์ ๋ง๋๋ค. - ์ฃผ๋ฌธ ์ํฐํฐ์ ๊ฒฝ์ฐ, ์ฃผ๋ฌธ ๊ด๋ จ๋ ๋ฐ์ดํฐ ๋ฟ ์๋๋ผ ๋ฐฐ์ก์ง ์ฃผ์ ๋ณ๊ฒฝ์ ์ํ ๊ธฐ๋ฅ๋ ํจ๊ป ์ ๊ณต
- ๋๋ฉ์ธ ๊ด์ ์์ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ณ ๊ธฐ๋ฅ ๊ตฌํ์
- ๋ ๊ฐ ์ด์์ ๋ฐ์ดํฐ๊ฐ ๊ฐ๋ ์ ์ผ๋ก ํ๋์ธ ๊ฒฝ์ฐ ๋ฐธ๋ฅ ํ์ ์ผ๋ก ํํ ๊ฐ๋ฅ (๋ฐธ๋ฅ๋ ๋ถํธ์ผ๋ก ๊ตฌํ ๊ถ์ฅ)
- ๋๋ฉ์ธ ๋ชจ๋ธ์ ์ํฐํฐ: ๋ฐ์ดํฐ์ ํจ๊ป ๋๋ฉ์ธ ๊ธฐ๋ฅ์ ํจ๊ป ์ ๊ณตํ๋ ๊ฐ์ฒด
-
๋๋ฉ์ธ ๋ชจ๋ธ์์ ์ ์ฒด ๊ตฌ์กฐ๋ฅผ ์ดํดํ๊ณ ๋ณต์กํ ๋๋ฉ์ธ ๋ชจ๋ธ์ ๊ด๋ฆฌํ๋๋ฐ ๋์์ด ๋๋ค.
-
์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ตฌํ ์ ๊ณ ๋ คํด์ผํ ๊ฒ์ด ๋ง๋ค. ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์ฑํ๋๋์ ๋ฐ๋ผ ๊ตฌํ์ด ๋ณต์กํด์ง๊ธฐ๋ ํ๊ณ , ํธ๋์ญ์ ๋ฒ์๊ฐ ๋ฌ๋ผ์ง๊ธฐ๋ ํ๊ธฐ ๋๋ฌธ
-
์ ํํ ๊ตฌํ ๊ธฐ์ ์ ๋ฐ๋ผ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ตฌํ์ ์ ์ฝ์ด ์๊ธฐ๊ธฐ๋ ํ๋ค.
-
๋ชจ๋ธ์ ์ดํดํ๋๋ฐ ๋์์ ์ฃผ๋ฉฐ, ์ผ๊ด์ฑ์ ๊ด๋ฆฌํ๋ ๊ธฐ์ค
- ์ ๋ง์ ๊ฐ์ฒด๋ฅผ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ก ๋ฌถ์ด์ ๋ฐ๋ผ๋ณด๋ฉด ์ข ๋ ์์ ์์ค์์ ๋๋ฉ์ธ ๋ชจ๋ธ ๊ฐ์ ๊ด๊ณ๋ฅผ ํ์ ํ ์ ์๋ค.
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ฒฝ๊ณ
-
์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ (์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ ์ํฐํฐ)
-
ํต์ฌ ์ญํ ) ๋๋ฉ์ธ ๊ท์น์ ๋ฐ๋ผ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ผ๊ด์ฑ์ด ๊นจ์ง์ง ์๋๋ก ํ๋ค.
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ํด ์๋ ์ํฐํฐ์ ๋ฐธ๋ฅ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๊ฐ ๊ตฌํํด์ผ ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
-
๊ฐ์ ์ ์ผ๋ก ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ด์ ๋ค๋ฅธ ์ํฐํฐ๋ ๋ฐธ๋ฅ ๊ฐ์ฒด์ ์ ๊ทผํ๊ฒ ๋๋ค. ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋จ์๋ก ๊ตฌํ -> ๋ด๋ถ ๊ตฌํ์ ์จ๊ฒจ
์บก์ํ
ํ๋๋ก ํ๋ค. -
๋๋ฉ์ธ ๋ก์ง์ ๋ง๊ฒ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ํ๋ฅผ ๊ด๋ฆฌ
-
๋ถ ํ์ํ ์ค๋ณต์ ํผํ๊ณ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๋ฅผ ํตํด์๋ง ๋๋ฉ์ธ ๋ก์ง์ ๊ตฌํํ๊ฒ ํ๋ ค๋ฉด?
- ๋จ์ํ ํ๋๋ฅผ ๋ณ๊ฒฝํ๋ set ๋ฉ์๋๋ฅผ ๊ณต๊ฐ(public) ๋ฒ์๋ก ๋ง๋ค์ง ์๋๋ค. (๋๋ฉ์ธ ๋ชจ๋ธ์์ ๊ณต๊ฐ set ๋ฉ์๋๋ ๊ฐ๊ธ์ ํผํ๋ค.)
- ๋๋ฉ์ธ ๋ชจ๋ธ์
์ํฐํฐ
๋๋ฐธ๋ฅ
์ ๊ณต๊ฐ set ๋ฉ์๋๋ง ๋ฃ์ง ์์๋ ์ผ๊ด์ฑ ๊นจ์ง ๊ฐ๋ฅ์ฑ ์ค์ด๋ ๋ค.
- ๋๋ฉ์ธ ๋ชจ๋ธ์
- ๋ฐธ๋ฅ ํ์
์ ๋ถ๋ณ์ผ๋ก ๊ตฌํํ๋ค.
- ๋ถ๋ณ ๋ฐธ๋ฅ ๊ฐ์ฒด์ ๊ฐ์ ๋ณ๊ฒฝํ๋ ค๋ฉด, ์๋ก์ด ๊ฐ์ฒด๋ฅผ ํ ๋นํด์ ๋ณ๊ฒฝํด์ผ ํ๋ค.
- ๋ฐธ๋ฅ ํ์ ์ ๋ด๋ถ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ฉด ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ๋ฅผ ํตํด์๋ง ๊ฐ๋ฅํ๋ค. -> ์ ๊ทธ๋ฆฌ๊ฑฐํธ ์ ์ฒด์ ์ผ๊ด์ฑ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์งํ ์ ์์!
- ๋จ์ํ ํ๋๋ฅผ ๋ณ๊ฒฝํ๋ set ๋ฉ์๋๋ฅผ ๊ณต๊ฐ(public) ๋ฒ์๋ก ๋ง๋ค์ง ์๋๋ค. (๋๋ฉ์ธ ๋ชจ๋ธ์์ ๊ณต๊ฐ set ๋ฉ์๋๋ ๊ฐ๊ธ์ ํผํ๋ค.)
-
-
๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์ง์์ ์ผ๋ก ์ฌ์ฉํ๋ ค๋ฉด RDBMS, NoSQL, ๋ก์ปฌ ํ์ผ๊ณผ ๊ฐ์ ๋ฌผ๋ฆฌ์ ์ธ ์ ์ฅ์์ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ๋ณด๊ดํด์ผ ํ๋ค. (์ด๋ฅผ ์ํ ๋๋ฉ์ธ ๋ชจ๋ธ = ๋ ํ์งํ ๋ฆฌ)
-
์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋จ์๋ก ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ณ ์กฐํํ๋ ๊ธฐ๋ฅ์ ์ ์ํ๋ค.
-
์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ ๊ฐ๋ ์ ์ผ๋ก ํ๋๋ก ๋ ํ์งํ ๋ฆฌ๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ์ ์ฒด๋ฅผ ์ ์ฅ์์ ์์ํ ํด์ผํ๋ค.
- Order ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๊ด๋ จ๋ ํ ์ด๋ธ์ด ์ธ๊ฐ ๋ผ๋ฉด ๋ ํ์งํ ๋ฆฌ๋ฅผ ํตํด์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ฃจํธ์ ๋งคํ๋ ํ ์ด๋ธ ๋ฟ ์๋๋ผ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ํ ๋ชจ๋ ๊ตฌ์ฑ์์๋ฅผ ์ํ ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ผ ํ๋ค.
- ex) Order ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ OrderLine, Orderer ๋ฑ ๋ชจ๋ ๊ตฌ์ฑ ์์ ํฌํจ ํด์ผ ํจ.
-
repository interface ๋ ๋๋ฉ์ธ ๋ชจ๋ธ ์์ญ์ ์ํ๋ฉฐ, ์ค์ ๊ตฌํ ํด๋์ค๋ infrastructure ์์ญ์ ์ํ๋ค.
-
์ด๋ค ๊ธฐ์ ์ ์ด์ฉํด์ ๋ ํ์ง๋กํฐ๋ฅผ ๊ตฌํํ๋๋์ ๋ฐ๋ผ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๊ตฌํ๋ ์ํฅ์ ๋ฐ๋๋ค.
- ex) ORM ๊ธฐ์ ์ค JPA/Hibernate ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๊ด๊ณํ ๋ชจ๋ธ์ ๊ฐ์ฒด ๋๋ฉ์ธ ๋ชจ๋ธ์ ๋ง์ถฐ์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
- ํํ ์์ญ, ์์ฉ ์์ญ, ๋๋ฉ์ธ ์์ญ ์ง์
- ๋๋ฉ์ธ ๊ฐ์ฒด์ ์์์ฑ ์ฒ๋ฆฌ, ํธ๋์ญ์ , SMTP Client, REST Client ๋ฑ ๋ค๋ฅธ ์์ญ์์ ํ์๋กํ๋ ํ๋ ์์ํฌ, ๊ตฌํ ๊ธฐ์ , ๋ณด์กฐ ๊ธฐ๋ฅ ์ง์
- ๋๋ฉ์ธ ์์ญ๊ณผ ์์ฉ ์์ญ์์ ์ธํ๋ผ์คํธ๋ญ์ฒ์ ๊ธฐ๋ฅ์ ์ง์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค, ๋ ์์ญ์ ์ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ธํ๋ผ์คํธ๋ญ์ฒ ์์ญ์ ๊ตฌํํ๋ ๊ฒ์ด ์์คํ
์ ๋ ์ ์ฐํ๊ณ ํ
์คํธํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด ์ค๋ค. -
DIP
โ
DIP
๊ฐ ์ฃผ๋ ๊ตฌํ์ ํธ๋ฆฌํจ ์ฅ์ ๋งํผ DIP์ ์ฅ์ ์ ํด์น์ง ์๋ ๋ฒ์์์ ์์ฉ ์์ญ๊ณผ ๋๋ฉ์ธ ์์ญ์์ ๊ตฌํ ๊ธฐ์ ์ ๋ํ ์์กด์ ๊ฐ์ ธ๊ฐ๋ ๊ฒ์ด ์ข๋ค.
(์ธํ๋ผ์คํธ๋ญ์ฒ์ ์์กด์ฑ์ ์์ ๋ ๊ฒ์ผ๋ก ์์นซ ๊ตฌํ์ ๋ ๋ณต์กํ๊ณ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ!)
ex, @Transactional
-
๋๋ฉ์ธ์ด ํฌ๋ฉด ํ์ ๋๋ฉ์ธ์ผ๋ก ๋๋๊ณ , ๊ฐ ํ์ ๋๋ฉ์ธ๋ง๋ค ๋ณ๋ ํจํค์ง๋ฅผ ๊ตฌ์ฑํ๋ค.
-
domain ๋ชจ๋์ ๋๋ฉ์ธ์ ์ํ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ธฐ์ค์ผ๋ก ํจํค์ง๋ฅผ ๊ตฌ์ฑํ๋ค.
-
๊ฐ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๋ชจ๋ธ๊ณผ ๋ ํ์งํ ๋ฆฌ๋ ๊ฐ์ ํจํค์ง์ ์์น์ํจ๋ค.
-
๋๋ฉ์ธ์ด ๋ณต์กํ๋ฉด ๋๋ฉ์ธ ๋ชจ๋ธ๊ณผ ๋๋ฉ์ธ ์๋น์ค๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๋ ํจํค์ง์ ์์น ์ํฌ ์ ์๋ค.
com.hyeon.order.domain.order: ์ ๊ทธ๋ฆฌ๊ฑฐํธ ์์น
com.hyeon.order.domain.service: ๋๋ฉ์ธ ์๋น์ค ์์น
- ์์ฉ ์๋น์ค๋ ๋ค์๊ณผ ๊ฐ์ด ๋๋ฉ์ธ ๋ณ๋ก ํจํค์ง ๊ตฌ๋ถํ ์ ์๋ค.
com.hyeon.catalog.application.product
com.hyeon.catalog.application.category
- ํธ๋์ญ์
๋ฒ์๋ ์์ ์๋ก ์ข๋ค.
- DB ๊ธฐ์ค์ผ๋ก ํ ํธ๋์ญ์ ์ด ํ ๊ฐ์ ํ ์ด๋ธ์ ์์ ํ๋ ๊ฒ๊ณผ ์ธ ๊ฐ์ ํ ์ด๋ธ ์์ ํ๋ ๊ฒ์ ์ฑ๋ฅ์์ ์ฐจ์ด ๋ฐ์
- ํ ํธ๋์ญ์ ์ ๋๊ฐ ์ด์์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์์ ํ๋ฉด ํธ๋์ญ์ ์ถฉ๋์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋์ผ๋ฉฐ, ๊ฐ์๊ฐ ๋ง์์ง ์๋ก ์ฒ๋ฆฌ๋๋ ๋จ์ด์ง๊ฒ ๋๋ค.
- ํ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์์ ๋ค๋ฅธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ์ํ๋ฅผ ๋ณ๊ฒฝ ํ๋ ๊ฒ์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๊ฐ์ ์์กด ๊ฒฐํฉ๋๋ฅผ ๋์ฌ ๊ฒฐ๊ณผ์ ์ผ๋ก ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๋ณ๊ฒฝ์ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
ํ๋๋ฅผ ์ด์ฉํด ๋ค๋ฅธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์ง์ ์ฐธ์กฐํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ๊ตฌํ์ ํธ๋ฆฌํจ์ ์ ๊ณตํ๋ค.
ํ์ง๋ง, ํธํ ํ์ ์ค์ฉ
, ์ฑ๋ฅ์ ๋ํ ๊ณ ๋ฏผ
, ํ์ฅ์ ์ด๋ ค์
๋ฌธ์ ๋ฅผ ์ผ๊ธฐ ์ํจ๋ค.
ID๋ฅผ ์ด์ฉํด์ ๋ค๋ฅธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์ฐธ์กฐ ํ๋ ๋ฐฉ๋ฒ์ ์ธ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ํ ์ํจ๋ค.
ID๋ฅผ ์ด์ฉํ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ์ฐธ์กฐ๋ ์ง์ฐ ๋ก๋ฉ๊ณผ ๊ฐ์ ํจ๊ณผ๋ฅผ ๋ง๋๋๋ฐ ์ง์ฐ ๋ก๋ฉ๊ณผ ๊ด๋ จ๋ ๋ํ์ ์ธ ๋ฌธ์ ๊ฐ N + 1 ์กฐํ ๋ฌธ์
์ด๋ค.
N + 1 ์กฐํ ๋ฌธ์
์กฐํ ๋์์ด N ๊ฐ ์ผ ๋ N ๊ฐ๋ฅผ ์ฝ์ด์ค๋ ํ๋ฒ์ ์ฟผ๋ฆฌ์ ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ค๋ ์ฟผ๋ฆฌ๋ฅผ N๋ฒ ์คํ ํ๋ ๊ฒ์ ๋งํ๋ค. ์ด๋ ๋ ๋ง์ ์ฟผ๋ฆฌ๋ฅผ ์คํํด์ ์ ์ฒด ์กฐํ ์๋๊ฐ ๋๋ ค์ง๋ ์์ธ์ด ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์กฐ์ธ์ ์ฌ์ฉ ํ๋ค.
- ID ์ฐธ์กฐ ๋ฐฉ์ -> ๊ฐ์ฒด ์ฐธ์กฐ ๋ฐฉ์ ๋ณ๊ฒฝ ํ๊ณ ์ฆ์๋ก๋ฉ์ ์ฌ์ฉํ๋๋ก ๋งคํ ์ค์ ์ ๋ฐ๊พธ๋ ๊ฒ.
- ID ์ฐธ์กฐ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด์ N+1 ์กฐํ ๋ฌธ์ ๋ฅผ ๋ฐ์ํ์ง ์๋๋ก ํ๊ธฐ ์ํด์๋? ์ธํ ์กฐ์ธ์ ์ด์ฉํด์ ์ ์ฉ ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
- JPA์์ ์กฐํ ์ ์ฉ ์ฟผ๋ฆฌ๋ฅผ ์คํ
- CQRS
JPA ์ด์ฉํ ๋งคํ ์ค์ ์ผ๋ก ID ์ฐธ์กฐ๋ก ์ด์ฉํ M:N ๋จ๋ฐฉํฅ ์ฐ๊ด ๊ตฌํ ๊ฐ๋ฅ.
@Entity
@Table(name = "product")
public class Product {
@EmbeddedId
private ProductId id;
@ElementCollection
@CollectionTable(name = "product_category",
joinColumns = @JoingColumn(name = "product_id"))
private Set<CategoryId> categoryIds;
...
}
์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ํฉํ ๋ฆฌ๋ก ์ฌ์ฉํ๋ฉด ๋๋ฉ์ธ์ ์์ง๋๋ฅผ ๋์ผ ์ ์๋ค.
์์) Product ์์ฑ ๊ฐ๋ฅํ์ง ํ๋จํ๋ ์ฝ๋์ Product๋ฅผ ์์ฑํ๋ ์ฝ๋๊ฐ ๋ถ๋ฆฌ ๋์ด ์๋ค.
public class RegisterProductService {
public ProductId registerNewProduct(NewProductRequest req) {
Store account = accountRepository.findStoreById(req.getStoreId());
checkNull(account);
if(account.isBlocked()) {
throw new StoreBlockedException();
}
ProductId id = productRepository.nextId();
Product product = new Product(id, account.getId, ...);
productRepository.save(product);
return id;
}
...
}
์ ์ฝ๋๋ ์ค์ํ ๋๋ฉ์ธ ๋ก์ง ์ฒ๋ฆฌ๊ฐ ์์ฉ ์๋น์ค์ ๋ ธ์ถ๋์๋ค. ์ด๋ป๊ฒ ์์ ํ ์ ์์๊น?
Product์ ๊ฒฝ์ฐ ์ ํ์ ์์ฑํ Store์ ์๋ณ์๋ฅผ ํ์๋ก ํ๋ค.
์ด ํํธ๋ก ๋ณด์์ ๋, ๋๋ฉ์ธ ๊ธฐ๋ฅ์ ๋ฃ๊ธฐ ์ํ ๋ณ๋์ ๋๋ฉ์ธ ์๋น์ค๋ ํฉํ ๋ฆฌ ํด๋์ค๋ฅผ ๋ง๋ค ์๋ ์์ง๋ง ์ด ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ์ ๋ ์ข์ ๊ณณ์ Store ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ค. ์ฆ. Store์ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด์ Product๋ฅผ ์์ฑํ๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Store์ Product๋ฅผ ์์ฑํ๋ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ฉด Product๋ฅผ ์์ฑํ ๋ ํ์ํ ๋ฐ์ดํฐ ์ผ๋ถ๋ฅผ ์ง์ ์ ๊ณตํ๋ฉด์ ๋์์ ์ค์ํ ๋๋ฉ์ธ ๋ก์ง์ ํจ๊ป ๊ตฌํํ ์ ์๊ฒ ๋๋ค.
public class Store extends Memeber {
/* Product ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์์ฑํ๋ ํฉํ ๋ฆฌ ์ญํ ์ ํ๋ค. */
public Product createProduct(ProductId newProductId, ...) {
if(isBlocked()) {
throw new StoreBlockedException();
}
return new Product(newProductId, getId(), ...);
}
}
โ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๊ฐ ๊ฐ๊ณ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด์ ๋ค๋ฅธ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์์ฑํด์ผ ํ๋ค๋ฉด, ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๊ณ ๋ คํด ๋ณผ ๊ฒ!
- ์ํฐํฐ์ ๋ฐธ๋ฅ ๋งคํ
- ๋ฐธ๋ฅ ์ปฌ๋ ์ ๋งคํ
- ์ ๊ทธ๋ฆฌ๊ฑฐํธ ๋ก๋ฉ ์ ๋ต๊ณผ ์์์ฑ ์ ํ
- ์๋ณ์ ์์ฑ ๊ธฐ๋ฅ
์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ์ด๋ค ์ ์ฅ์์ ์ ์ฅํ๋๋์ ๋ฐ๋ผ ๋ ํฌ์งํฐ๋ฆฌ๋ฅด ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๋ค.
๋ ํฌ์งํ ๋ฆฌ ์ธํฐํ์ด์ค๋ ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๊ฐ์ด ๋๋ฉ์ธ ์์ญ
์ ์ํ๊ณ ,
๋ ํฌ์งํ ๋ฆฌ๋ฅผ ๊ตฌํํ ํด๋์ค๋ ์ธํ๋ผ ์คํธ๋ญ์ฒ ์์ญ
์ ์ํ๋ค.