- ์ ๋ต์ (strategic) ๋์์ธ์ ์ถ์์ ์ธ ์ ์ฒด๋ฅผ ๋ค๋ฃจ๋ ๋ฐ๋ฉด ์ ์ ์ (tactical) ๋์์ธ์ ํด๋์ค์ ๋ชจ๋์ ๋ค๋ฃฌ๋ค
- ์ ์ ์ ์ค๊ณ์ ๋ชฉ์ ์ ๋๋ฉ์ธ ๋ชจ๋ธ์ ์ค์ ์ฝ๋๋ก ๊ตฌ์ฒดํํ๋ ๊ฒ
- ์ ๋ต์ ์ค๊ณ๋ฅผ ๋ง์น ๋ค์, ์ ์ ์ ์ค๊ณ๋ก ์ฝ๋๋ฅผ ๊ตฌ์ฒดํ์ํค๋ฉด์ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฉด ๋ค์ ์ ๋ต์ ์ค๊ณ๋ฅผ ๋ณด์ํ๋ ๋ฐ๋ณต์ ์ธ ๋จ๊ณ๋ฅผ ์งํํ๋ค
-
Value Objects(VO)
- ๋๊ฐ์ VO ๋ด์ ์๋ ๊ฐ๋ค์ด ๊ฐ๋ค๋ฉด ๋๊ฐ์ VO๋ ๊ฐ์ VO๋ก ๊ฐ์ฃผ๋๋ค
- immutable ๋ก ๋ง๋ค์ด์ผ ํ๋ค (VO์ ์ํ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ์๋ก์ด VO๋ฅผ ๋ง๋ ๋ค)
- VO ๋ด์๋ ๋จ์ํ ๊ฐ๋ค์ด ์๋ business logic๋ ํฌํจํ ์ ์๋ค
- VO๊ฐ immutable ์ด๊ธฐ ๋๋ฌธ์ business logic์ thread-safe ํ๋ค
- ์ด๋ฌํ ์ด์ ๋๋ฌธ์ domain์ VO๊ฐ ๋ง์์๋ก ์ข๋ค
- ๊ฐ๊ธ์ VO ์ size ๋ฅผ ์๊ณ ์์ง๋๊ฐ ๋๊ฒ ์ ์งํ๋ ๊ฒ์ด ์ข๋ค
- ์ ์ง๋ณด์์ ์ฌ์ฌ์ฉ์ด ์ฝ๋ค
- VO๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ business ์๋ฏธ๋ฅผ ๊ฐ์ง๋ ์ฌ๋ฌ๊ฐ์ ๊ฐ๋ค์ ๋ํํด ํ๋์ ๊ฐ์ฒด๋ก ๋ง๋ ๋ค
- ex. BigDecimal ๋์ ์ BigDecimal์ ํฌํจํ๋ Money VO
- ex. phone number ๋ฅผ string ์ผ๋ก ํํํ๊ธฐ๋ณด๋ค string์ ํฌํจํ๋ PhoneNumber VO
- ์ฅ์
- ๊ฐ์ ๋ช ํํ ์๋ฏธ๊ฐ ๋ถ์ฌ๋๋ค
- ๊ฐ์ ๋ํด business operation ์ ์ถ๊ฐํ ์ ์๋ค
- ๊ฐ์ ๋ํ ๊ฒ์ฆ(ex. null check)์ VO ์์ฑ์์์ ํ ์ ์๋ค
-
Entities
- ๊ณ ์ ์ ID ๋ฅผ ๊ฐ์ง๋ ๊ฐ์ฒด(Entity์ ์๋ช ์ฃผ๊ธฐ ๋์ ID๋ ๋ณํ์ง ์๋๋ค)
- ๊ฐ์ฒด ๋ด์ ๊ฐ์ด ๋ฌ๋ผ๋ ID๊ฐ ๊ฐ์ผ๋ฉด ๊ฐ์ entity๋ก ๊ฐ์ฃผ๋๋ค
- ๊ฐ์ฒด ๋ด์ ๊ฐ์ด ๊ฐ์๋ ID๊ฐ ๋ค๋ฅด๋ฉด ๋ค๋ฅธ entity๋ก ๊ฐ์ฃผ๋๋ค
- VO ์ ๋ค๋ฅด๊ฒ mutable ํ๋ค
- ๊ฐ์ ๋ณ๊ฒฝํ ๋, setter ๋ฅผ ์ฌ์ฉํ ์๋ ์๊ณ ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋์ง์ ๋ํ ์ด์ ๋ฅผ ๋ํ๋ด๋
๊ฐ ๋ณ๊ฒฝ ๋ฉ์๋๋ฅผ ๋ง๋ค ์๋ ์๋ค
- ex. setEndDate(finalDay) ๋์ terminateContract(reason, finalDay)
- setFirstName(..) , setLastName(..) ๋์ changeName(firstName, lastName, reason, effectiveAsOfDate)
- ๊ฐ์ ๋ณ๊ฒฝํ ๋, setter ๋ฅผ ์ฌ์ฉํ ์๋ ์๊ณ ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด์ผ ํ๋์ง์ ๋ํ ์ด์ ๋ฅผ ๋ํ๋ด๋
๊ฐ ๋ณ๊ฒฝ ๋ฉ์๋๋ฅผ ๋ง๋ค ์๋ ์๋ค
-
Entity or Value Object?
- ๊ฐ์ ๊ฐ๋ ์ด ์ํฉ์ ๋ฐ๋ผ Entity๊ฐ ๋ ์๋ ์๊ณ VO ๊ฐ ๋ ์๋ ์๋ค
- VO ๊ฐ immutable ํ๊ณ ์ฌ์ด์ฆ๊ฐ ๋ ์๊ธฐ ๋๋ฌธ์ entity๋ฅผ ๊ฐ๋ฅํ ์ ๊ฒ, VO๋ฅผ ๊ฐ๋ฅํ ๋ง์ด ์ ์งํ๋ ๊ฒ์ด ์ข๋ค
-
Aggregates
-
๋ค์๊ณผ ๊ฐ์ ํน์ฑ์ ๊ฐ์ง๊ณ ์๋ entity ์ VO ์ ์งํฉ
-
aggregate ๋ ์๋์ ๊ฐ์ ์กฐ๊ฑด์ ๋ง์กฑ์์ผ์ผ ํ๋ค
-
entity ๋ฅผ aggregate root ๋ก ์ฌ์ฉํ ๊ฒ์ด์ง , aggregate root ์๋์ ๋ ๊ฒ์ธ์ง(local entity) ๊ฒฐ์ ํด์ผ ํ๋ค
- local entity ๋ ๋ค๋ฅธ aggregate ์์ ์ฐธ์กฐ๋ ์ ์๊ธฐ ๋๋ฌธ์, aggregate ๋ด์์๋ง ๊ณ ์ ํ ID๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค
- aggregate root ๋ก ์ฌ์ฉ๋๋ entity ๋ ์ธ๋ถ์์ ์ฐธ์กฐ๋ ์ ์๊ธฐ ๋๋ฌธ์ global unique ํ ID๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค
-
entity ๋ฅผ aggregate root๋ก ์ฌ์ฉํ ์ง ์๋์ง๋ฅผ ์ด๋ค ๊ธฐ์ค์์ ํ๋จํ ๊น?
- entity ๊ฐ application ๋ด์์ ์ด๋ป๊ฒ ์ ๊ทผ๋๋๊ฐ?
- entity ๊ฐ ID ๋ก ๊ฒ์๋๋ค๋ฉด aggregate root ์ด๋ค
- ๋ค๋ฅธ aggregate ์์ ์ด entity๋ฅผ ์ฐธ์กฐํด์ผ ํ๋ค๋ฉด aggregate root ์ด๋ค
- application ์์ entity๊ฐ ์ด๋ป๊ฒ ๋ณํ๋๋๊ฐ?
- ๋ ๋ฆฝ์ ์ผ๋ก entity ๊ฐ ๋ณ๊ฒฝ๋๋ค๋ฉด aggregate root
- ๋ค๋ฅธ entity ๊ฐ ๋ณ๊ฒฝ๋์ด์ผ ์ด entity๊ฐ ๋ณ๊ฒฝ๋๋ค๋ฉด ์ด entity ๋ local entity
-
aggregate root ๊ฐ aggregate ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๋ฐฉ๋ฒ
- ๋ชจ๋ ์ํ ๋ณ๊ฒฝ์ aggregate ๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋๋ก ๊ฐ์ ํ๋ค
- local entity ์์ ์ํ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด aggregate root ๋ก ํต์งํ๋ค
-
-
Aggregate Design Guidelines
-
aggregate ๋ฅผ ์๊ฒ ์ ์งํ๊ธฐ
- aggregate ๊ฐ ํต์งธ๋ก DB์ ์ ์ฅ๋๊ณ ๊ฒ์๋๊ธฐ ๋๋ฌธ์ ์ฌ์ด์ฆ๊ฐ ์์์ผ ์ฑ๋ฅ์ด ๋ ์ข๋ค
- aggregate ํฌ๊ธฐ๊ฐ ์์ผ๋ฉด, ๋น์ฆ๋์ค ์ผ๊ด์ฑ์ ์งํค๊ธฐ ๋ ์ฌ์์ง๋ค
-
ID๋ก ๋ค๋ฅธ aggregate ๋ฅผ ์ฐธ์กฐํ๊ธฐ
- ๋ค๋ฅธ aggregate ๋ฅผ ์ง์ ์ฐธ์กฐํ์ง ๋ง๊ณ , aggregate root ID ๋ฅผ ๋ํํ๋ VO๋ฅผ ๋ง๋ค๊ณ , VO๋ก aggregate ๋ฅผ ์ฐธ์กฐํด๋ผ
-
์ฌ๋ฌ๊ฐ์ aggregate์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด์ domain event๋ฅผ ์ฌ์ฉํ๊ธฐ
-
๋๊ด์ ๋ฝ(optimistic locking) ์ ์ฌ์ฉํ๊ธฐ
- aggregate์ ์ค์ํ ํน์ง์ ๋น์ฆ๋์ค ์ผ๊ด์ฑ, ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๊ฒ์ด๋ค
- aggregate๋ฅผ ์ ์ฅํ ๋, ๋๊ฐ์ ์ ์ฅ ์ฐ์ฐ์ด ์๋ก ์ถฉ๋ํ๋ฉด aggregate๊ฐ ๊นจ์ง ์ ์๊ธฐ ๋๋ฌธ์ aggregate๋ฅผ ์ ์ฅํ ๋ optimistic lock์ ์ฌ์ฉํ๋ค
- ๋๊ด์ ๋ฝ(optimistic lock) ์ ๋น๊ด์ ๋ฝ(pessimistic lock) ๋ณด๋ค ๊ตฌํํ๊ธฐ๊ฐ ๋ ์ฝ๋ค
-
-
Domain Events
-
๋๋ฉ์ธ ์ด๋ฒคํธ๋ ๋๋ฉ์ธ ๋ชจ๋ธ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค
- ๋๋ฉ์ธ์ ์ ์ฒด(aggregate root) ๋๋ ์ผ๋ถ(aggregate root์ ํน์ ์์ฑ)๋ฅผ ๋ณ๊ฒฝํ๋๋ฐ ์ฌ์ฉ๋๋ค
-
์ ํ์ ์ผ๋ก ์๋์ ๊ฐ์ ์์ฑ์ ๊ฐ์ง๋ค
- immutable
- ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ timestamp
- ๋ค๋ฅธ ์ด๋ฒคํธ์ ๊ตฌ๋ณํ๋๋ฐ ๋์์ด ๋๋ ๊ณ ์ ID
- aggregate root๋ domain service์ ์ํด publish ๋๋ค
-
domain event listener๊ฐ domain event๋ฅผ ๋ฐ๋๋ค
-
domain event listener๋ event ๋ฅผ publish ํ๋ ํธ๋์ญ์ ๊ณผ ๋ณ๋๋ก ์คํํ๋ ๊ฒ์ด ์ข๋ค
-
domain event ์ ๊ฐ์ฅ ํฐ ์ด์ ์ ์์คํ ์ ํ์ฅ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค๋ ์ ์ด๋ค
- ๊ธฐ์กด์ ์กด์ฌํ๋ ์ฝ๋๋ฅผ ๊ณ ์น์ง ์๊ณ ์๋ก์ด ๋น์ฆ๋์ค ๋ก์ง์ trigger ํ ์ ์๋ค
-
event sourcing
- ์์คํ ์ ์ํ๊ฐ ์ด๋ฒคํธ์ ์์ํ๋ ๋ก๊ทธ๋ก ์ ์ฅ๋๋ ๋์์ธ ํจํด
- ๊ฐ๊ฐ์ ์ด๋ฒคํธ๋ ์์คํ ์ ์ํ๋ฅผ ๋ณ๊ฒฝํ๊ณ ์์๊ฐ๊ฐ ๊ณ์ฐ๋๋ ํ์ฌ ์ํ๊ฐ ์ด๋ฒคํธ ๋ก๊ทธ์ ์ ์ฅ๋๋ค
- ํ์ฌ ์ํ๋ณด๋ค ํ์คํ ๋ฆฌ๊ฐ ๋ ์ค์ํ ๋ ์ฌ์ฉ๋๋ค
- domain event ๊ฐ event sourcing ํจํด์ ๊ตฌํํ๋๋ฐ ์ฌ์ฉ๋๋ค
- domain model ์ ์ํ๋ฅผ ๋ฐ๊พธ๋ ๋ชจ๋ ์ฐ์ฐ์ domain event๋ฅผ ๋ฐํํ๋ฉฐ ์ด ์ด๋ฒคํธ๊ฐ ๋ก๊ทธ๋ก ๋จ๋๋ค
-
-
Distributing Domain Events
- domain event๋ ๋ฆฌ์ค๋์๊ฒ ์์ ์ ์ผ๋ก ์ ๋ฌ๋ ์ ์์ ๋์๋ง ์ฌ์ฉํ ์ ์๋ค
- event listener๊ฐ ์ด๋ฒคํธ ์์ ์ ์คํจํด์ ๋ค์ ๋ณด๋ด์ผ ํ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด์ผ ํ๋๊ฐ?
-
Distribution Through a Message Queue
-
Distribution Through an Event Log

- ์ถ๊ฐ์ ์ธ component๋ฅผ ํ์๋ก ํ์ง ์๋ ๋์ ์ฝ๊ฐ์ ์ฝ๋ฉ์ด ํ์ํ๋ค
- domain event ๊ฐ ๋ฐํ๋ ๋, event log์ append๋๋ค
- domain event listener๊ฐ event log๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ํด๋งํ๋ค
- ์ถ๊ฐ์ ์ธ component๊ฐ ํ์ ์๊ณ , ์๋ก์ด listener๊ฐ ๋ค์ด์๋ ์ ์ฒด ํ์คํ ๋ฆฌ๊ฐ ๋ณด์กด๋๋ค(์ฅ์ )
- ์ถ๊ฐ์ ์ธ ๊ตฌํ์ ํ์๋ก ํ๋ฉฐ publish์ subscribe ์ฌ์ด์ ์ง์ฐ์ด ๋ฐ์ํ ์ ์๋ค(๋จ์ )
-
-
A Note on Eventual Consistency





