han jeong heon
@scant10
Students
2,790
Reviews
190
Course Rating
4.6
ํ ๊ตญ๋ด SI์ ์ฒด ์ํํธ์จ์ด ์์ง๋์ด(SA,AA)
๋ค์์ ๋๊ท๋ชจ ์ฐจ์ธ๋ ํ๋ก์ ํธ ๊ฐ๋ฐ๋ฐฉ๋ฒ๋ก ๋ฐ ์ค๊ณ๋ฐฉ๋ฒ ๋ฆฌ๋ฉ
๋ช ์ง๋, ์์ธ๊ณผํ๊ธฐ์ ๋ ํด๋ผ์ฐ๋,SW๊ณผ๋ชฉ ๊ฐ์
SK C&C,ํ๊ตญ์ ๋ณด๊ธฐ์ ์ฐ๊ตฌ์(kitri), LG์ ์ MSA๊ณผ์ ๊ฐ์
๋ฉํฐ์บ ํผ์ค, ํ๊ตญํ์คํํ, ํ๊ตญํ์งํํ MSA ๊ณผ์ ๋ฉํ ๋ง,์คํ๋ก์ค์์นด๋ฐ๋ฏธ ์น๊ฐ๋ฐ ๊ณผ์ ๋ฉํ ๋ง
์ ๋ฌธ๋ถ์ผ : ๊ฐ๋ฐ๋ฐฉ๋ฒ๋ก , ์ํํธ์จ์ด ์ํคํ ์ฒ/์ค๊ณ/๊ฐ๋ฐ ๊ธฐ๋ฒ
22๋ , ์ํค๋ถ์ค "๋๋ฉ์ธ์ฃผ๋๋ก ์์ํ๋ ๋ง์ดํฌ๋ก์๋น์ค ๊ฐ๋ฐ", ์ ์
๊ตญ๊ฐํ์๊ต์ก์งํฅ์, K-MOOC "Microservice ์ค๊ณ ๋ฐ ๊ตฌํ " ๊ฐ์ข ๊ฐ๋ฐ ๋ฐ ๊ฐ์


Courses
Reviews
- Microservice Design (with EventStorming, DDD)
- Microservice Design (with EventStorming, DDD)
- Understanding Microservices (with MSA Patterns)
- Microservice Design (with EventStorming, DDD)
- Microservice Implementation (with EDA, Hexagonal, DDD)
Posts
Q&A
MSA ์ง๋ฌธ์ด ์์ต๋๋ค
๋ค ๊ฐ์์์ ๋๋ค. ํ๋ํ๋ ๋ต๋ณ๋๋ฆฌ๋ฉด,db๋ฅผ ๋๋๋ฉด ์กฐ์ธ์ด ๊นจ์ง๋?๋ค. ์๋น์ค๊ฐ ๊ฐ๊ฐ DB๋ฅผ ๊ฐ์ง๋ฉด(๋ ๋ฆฝ DB) ๊ธฐ๋ณธ์ ์ผ๋ก DB ๋ ๋ฒจ JOIN์ ๋ชป ํฉ๋๋ค.๊ทธ๋์ MSA์์๋ ๋ณดํต ์ด๋ ๊ฒ ๋ฐ๊ฟ๋๋ค.(A) ์กฐํ JOIN โ โAPI ์กฐํฉ(Composition)โํ๋ฉด/์กฐํ๊ฐ ํ์ํ๋ฉดBFF/์กฐํ์ฉ API๊ฐ ์ฌ๋ฌ ์๋น์ค์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํฉ์ณ์ ๋ด๋ ค์ค๋จ์ : ํธ์ถ์ด ์ฌ๋ฌ ๋ฒ(๋คํธ์ํฌ ๋น์ฉ), ์ฑ๋ฅ/์ฅ์ ์ ํ ๊ณ ๋ ค ํ์(B) ์กฐํ JOIN โ โ์ฝ๊ธฐ ์ ์ฉ ๋ชจ๋ธ(Projection) / CQRSโ์์ฃผ ์ฐ๋ ์กฐํ๋์ด๋ฒคํธ/๋๊ธฐํ๋ก ์ฝ๊ธฐ ์ ์ฉ ํ ์ด๋ธ์ ๋ฐ๋ก ๋ง๋ค์ด์๊ฑฐ๊ธฐ์๋ JOIN์ด ๊ฐ๋ฅํ๊ฒ ๋ง๋ฆ์ค๋ฌด์์ ์ ์ผ ํํ ํด๋ฒ ์ค ํ๋๊ทธ๋ผ JOIN ํ๋ค๊ฐ DB ๋๋๋ฉด ์ฟผ๋ฆฌ ํจ์จ ๋จ์ด์ง๋์?โ๊ทธ๋ด ์ ์์ด์. ํนํ โ๋ชจ๋ ธ๋ฆฌ์ค์์ SQL JOIN ํ ๋ฐฉโ์ด๋ ๊ฑธMSA์์ โ์๋น์ค 3๊ฐ ํธ์ถ + ์กฐํฉโ์ผ๋ก ๋ฐ๊พธ๋ฉด ์ง์ฐ์ด ๋ ์ ์์ต๋๋ค.๊ทธ๋์ ์ ํ ์ ํ๋จ ๊ธฐ์ค์ ์ด๋ ๊ฒ ์ก์ผ๋ฉด ๋ฉ๋๋ค.JOIN์ด ๋ง์๋ฐ๋ MSA๋ก ๊ฐ์ผ ํ๋ ๊ฒฝ์ฐํ/๋ฐฐํฌ/ํ์ฅ/์ฅ์ ๊ฒฉ๋ฆฌ๊ฐ ๋ ์ค์ํ ๋๋๋ฉ์ธ์ด ์ปค์ ธ์ ๋ณ๊ฒฝ ์ํฅ๋๊ฐ ๋๋ฌด ํด ๋JOIN์ด ๋๋ฌด ํต์ฌ์ด๊ณ ์ค์๊ฐ/๊ณ ์ฑ๋ฅ์ด ์ ๋ ์กฐ๊ฑด์ด๋ฉด๋ฌด๋ฆฌํ๊ฒ ์ชผ๊ฐ์ง ์๊ฑฐ๋์ชผ๊ฐ๋๋ผ๋ ์กฐํ๋ ๋ณ๋ ์ฝ๊ธฐ ๋ชจ๋ธ๋ก ํ์ด์ผ ํฉ๋๋ค(CQRS/Projection)๋ฐ์ดํฐ ๋ ์ดํฌ ๋ง๋ค ํ์ด๋ฐ? ๋ค, ๋ฐ๋ก ๋ฐ์ดํฐ๋ ์ดํฌ๋ก ๊ฐ๋ ๊ฑด ์๋๋๋ค.๋ณดํต์ CQRS, ๋จธํฐ๋ฆฌ์ผ๋ผ์ด์ฆ๋ ๋ทฐ, ์ฝ๊ธฐ ์ ์ฉ ์กฐํ ์๋น์ค๋ฅผ ๋จผ์ ๊ณ ๋ คํ๊ณ ,๊ทธ๊ฑธ๋ก ๊ฐ๋น์ด ์ ๋ ๋งํผ ๋ฐ์ดํฐ ์ยท์กฐํ ๋ณต์ก๋ยท๋ถ์ ์๊ตฌ๊ฐ ์ปค์ง ๋๋ฐ์ดํฐ๋ ์ดํฌ(DWH/๋ ์ดํฌํ์ฐ์ค)๋ก ๊ฐ๋ ๊ฒ ์ผ๋ฐ์ ์ธ ์์์ ๋๋ค.๊ฐ์ฌํฉ๋๋ค.
- 0
- 1
- 30
Q&A
๋๋ฉ์ธ ์ง๋ฌธ์์ต๋๋ค
๋ค ๊ฐ์์์ ๋๋ค. ์๋ ๋ต๋ณ์ฒ๋ผ, ๊ธฐ์ ์ ๋น์ง๋์ค ์ ๋ต,์ฑ๊ฒฉ ๋ณํ๋, ์กฐ์ง๊ตฌ์ฑ์์ ์ญ๋์ด ์ฑ์ฅ์ ๋ฐ๋ผ ๋๋ฉ์ธ ์ ํ์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ๋๋ฉ์ธ์ depth์ ๋ํด ๋ง์ ์ฃผ์ จ๋๋ฐ, ์๋ง๋ ์ ๋ฌด๋ถํด์ ๋์ค์ depth๋ฅผ ์ ๊ธธํ์๋ ๋ฏ ํฉ๋๋ค. ์๋ง๋ ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ์ ๋ฌธ์ ์์ญ์ผ๋ก ์ ์๋๋ ๋๋ฉ์ธ์ด ๊ณ์ธตํ์ธ ๋ฏ ํด ๋ณด์ด๋ค์. ์ฐ์ ์๋น์ค ์ฑ์ฅ์ ๋ฐ๋ผ ๋ณํ ํ ์ ์๋ค๋ ๋ต๋ณ์ ๋๋ฆฌ๊ณ , ๊ตฌ์ฒด์ ์์๋ฅผ ๋ค์ด ์ฃผ์๋ฉด ๋ ์์ธํ ๋ต๋ณ์ ๋๋ฆด ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
- 0
- 2
- 22
Q&A
ํ์ฌ์๋ ๊ฐ์์ ๋์ผํ ๋ฐฉ์์ ์ฌ์ฉํ๊ณ ๊ณ์ค์ง ๊ถ๊ธํฉ๋๋ค.
์ข์ ํผ๋๋ฐฑ ๊ฐ์ฌํฉ๋๋ค!๋ง์ํ์ ๋๋ก ๊ฐ์์์ ๋ค๋ค๋ Event Storming ๊ธฐ๋ฐ์ ๋๋ฉ์ธ ๋ถ๋ฆฌ ๋ฐฉ์์ ์ง๊ธ๋ ์ฌ์ ํ ์ ์ฐ์ด๊ณ ์์ต๋๋ค.๋ค๋ง ์ค๋ฌด๋ฅผ ํ๋ฉด์ ์กฐ๊ธ ๋ ๊ตฌ์ฒด์ ์ธ ๊ธฐ์ค๊ณผ ๊ฐ์ด ์์ฌ์, ์์ ๋ณด๋ค ์ ๊ตํ๊ฒ ๋ค๋ฌ์ด์ง ๋ถ๋ถ์ด ์์ด์.1โฃ ์ค์ฌ์ ์ฌ์ ํ โEvent Stormingโํต์ฌ์ ์ฌ์ ํ ubiquitous language ๋ก ์ด๋ฒคํธ ํ๋ฆ์ ํ์ ํ๋ ๊ฑฐ์์.๋ค๋ง ์์ ๋ณด๋ค ์ด๋ฒคํธ ๊ฐ ๊ฒฝ๊ณ(boundary) ๋ฅผ ์ ํ ๋ ์ข ๋ ๋ช ํํ ๊ธฐ์ค์ ์๋๋ค.๋จ์ํ โ์ ๋ฌด์ ์ผ๋ก ์๋ฏธ ์๋ ์ด๋ฒคํธโ๊ฐ ์๋๋ผโ โ๋๊ธฐ์ ๊ฒฐ๊ณผ๊ฐ ์๊ฒฐ๋๋ ์ต์ ๋จ์โ๋ฅผ ํ๋์ ์๋ธ๋๋ฉ์ธ์ผ๋ก ๋ด ๋๋ค.์ด๋ ๊ฒ ํ๋ฉด ๋์ค์ ๋ง์ดํฌ๋ก์๋น์ค๋ก ์ ํํ ๋ ํธ๋์ญ์ ์ด๋ ๋ฐ์ดํฐ ์ผ๊ด์ฑ ๊ด๋ฆฌ๊ฐ ํจ์ฌ ์์ฐ์ค๋ฌ์์ง๋๋ค.2โฃ Context Mapping์ ์ถ๊ฐ๋ ๊ด์ ๊ณผ๊ฑฐ์๋ ์ ๋ฌด ํ๋ฆ ์ค์ฌ์ ๊ฒฝ๊ณ๋ฅผ ๋ดค๋ค๋ฉด,์ง๊ธ์ ์ฌ๊ธฐ์ โ๋ฐ์ดํฐ ์์ ๊ถโ๊ณผ โ๋ณ๊ฒฝ ์ฃผ๊ธฐโ ๋ ๊ฐ์ด ๋ด ๋๋ค.์ฆ ์์ ์๋ '์ด๋ฒคํธ ํ๋ก์ฐ ์ค์ฌ'์ด์๋ค๋ฉด ํ์ฌ๋ '์ด๋ฒคํธ + ๋ฐ์ดํฐ ์์ ๊ถ + ๋ณ๊ฒฝ ์ฃผ๊ธฐ' ๋ ์ดํด์ ๋๋ฉ์ธ ๊ฐ ๊ฒฐํฉ๋ ์ต์ํํ๋ ค๊ณ ํ๊ณ ์์ต๋๋ค.์ด๋ ๊ฒ ๋ณด๋ฉด ์ ๋ฌด์ ์ผ๋ก ๋ถ๋ฆฌ๋ผ ์์ด๋ ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ๊ฐํ๊ฒ ๋ฌถ์ฌ ์๋ ์์ญ์ ์ด๊ธฐ์ ๊ตฌ๋ถํ๊ธฐ ์ฌ์์.3โฃ โDomain Canvasโ ๋ณํ์์ฆ์ Event Storming ์ดํ ๊ฐ ๋๋ฉ์ธ์ Domain Canvas ํํ๋ก ๊ตฌ์ฒดํํฉ๋๋ค.์ฆ,๋๋ฉ์ธ์ ๋ชฉ์ ์ฃผ์ ์กํฐ / ์ ์ฆ์ผ์ด์ค๋ํ ์ํฐํฐ์ธ๋ถ ์ฐ๋ ํฌ์ธํธํ ์ฑ ์(ownership)์ ํ ์ฅ์ ์ ๋ฆฌํด์ ๋๋ฉ์ธ ๋จ์์ ์ฑ ์๊ณผ ํ๋ ฅ ๊ด๊ณ๋ฅผ ๋ช ํํ ํด๋์ฃ .์ด ์ ๋๋ก ๋ต๋ณ ๋๋ฆด ์ ์๊ฒ ๋ค์. ๊ฐ์ฌํฉ๋๋ค.
- 0
- 2
- 49
Q&A
๊ฐ์๋ณด๋ค ๋ฐ๋ก ์ฌ์ญค๋ด ๋๋ค.
์๋ ํ์ธ์ ๊ฐ์์ ํ์ ํ์ ๋๋ค. ๋ต๋ณ๋๋ฆฌ๋ฉด1. ๊ฐ์์์ model์ ์ฌ์ฉํ ์ด์ ๊ฐ์์์๋ ๋๊ฐ์ง๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ตฌ์กฐ๋ฅผ ์ก์ผ๋ฉด ์๋ฌด๋๋ ๋ณต์กํด ์ง๊ณ , ํต์ฌ ๊ฐ๋ ์ ๋ฌ์ด ์ด๋ ต๊ธฐ ๋๋ฌธ์ model ์ JPA ๋งคํ์ ํ์ต๋๋ค.์ค์ ๋ก๋ ์์ AI๊ฐ ๋ต๋ณํ ๊ฒ์ฒ๋ผ Hexagonal Architecture์์ domain model๊ณผ persistence entity๋ ์๋ก ๋ค๋ฅธ ์ฑ ์์ ๊ฐ์ง๋ฏ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ ๋ง์ต๋๋ค.๋ค๋ง ์ค๋ฌด์์๋ ์ด๋ ๋น์ง๋์ค ๋๋ ๋ง์ดํฌ๋ก์๋น์ค ์ฑ๊ฒฉ์ ๋ฐ๋ผ, ์๊ฒฉํ๊ฒ ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ๋ฅผ ์ค์ํ ์ ์๊ณ , ์ด๋์ ๋ ๋ชจ๋ธ ๋ด๋ถ์ or mapping๋ฅผ ํจ๊ป ํ๋ ํํ์ ์งํํ ์๋ ์์ ๊ฒ ๊ฐ์ต๋๋ค.2. ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ์์์ ์ผ๋ฐ์ ์ธ ๊ตฌ์ฑ์๊ฒฉํ๊ฒ ์ค์ํ๋ ค๊ณ ํ๋ค๋ฉด ๋ณดํต ์๋์ ๊ฐ์ด ํจํค์ง๋ฅผ ๋๋์ด ๊ด๋ฆฌํฉ๋๋ค. framework โโโ jpaadapter โโโ entity โ JPA Entity ํด๋์ค๋ค ์์น domain โโโ model โ ์์ ๋น์ฆ๋์ค ๋ชจ๋ธ (์ ๊ทธ๋ฆฌ๊ฒ์ดํธ ๋ฃจํธ, VO ๋ฑ) 3. ๊ด๊ณ์ ์ญํ ๊ตฌ๋ถ ์ด๋ ๊ฒ ๊ตฌ๋ถ ํ์ ๋ ์ฑ ์ ๋ฐ ํน์ง์ ๋ค์๊ณผ ๊ฐ์์.domain.model :๋น์ฆ๋์ค ๊ท์น๊ณผ ๋๋ฉ์ธ ๋ก์ง . JPA, Spring ๋ฑ ์ธ๋ถ ๊ธฐ์ ์์กด ์์jpaadapter.entity :DB ๋งคํ ์ ์ฉ ํด๋์ค , @Entity, @Table ๋ฑ JPA Annotation ์ฌ์ฉ๋ ๊ณ์ธต์ Mapper๋ฅผ ํตํด ์ฐ๊ฒฐํฉ๋๋ค.Entity โ Domain Model ๋ณํ ์ฝ๋๊ฐ ์ด ๊ณ์ธต์์ ๋ด๋น๋ฉ๋๋ค.์ด๋ ๊ฒ ํ๋ฉด ๋๋ฉ์ธ์ ํ๋ ์์ํฌ์ ๋ ๋ฆฝ์ ์ผ๋ก ์ ์ง๋๊ณ , JPA ๊ต์ฒด๋ ๋ค๋ฅธ persistence ์ ๋ต ๋์ ์ ์ํฅ์ด ์ต์ํ๋ฉ๋๋ค.๋ต๋ณ์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค. ^ ^
- 0
- 2
- 57
Q&A
Aggregate ํ์์ ๊ผฌ๋ฆฌ๋ฅผ ๋ฌด๋ Entity ๋?
์๋ ํ์ธ์ ๊ฐ์์ ํ์ ํ์ ๋๋ค.domain์ ๊ตฌํํ ๋ ์ด๋ฐ ์ค์ฒฉ ๊ณ์ธตํ๋ ๋ชจ๋ธ์ ๋๋ฉ์ธ ๋ชจ๋ธ์์ ๋ฐ๋์งํ ๊ตฌ์กฐ๋ ์๋ ๊ฒ ๊ฐ๋ค์.์ฆ ๋๋ฉ์ธ ๋ชจ๋ธ์ ํ ๋จ์๊ฐ ๋๋ ์ด๊ทธ๋ฆฌ๊ฒ์ดํธ๋ฅผ ๋ชจ๋ธ๋ง ํ ๋, ์ฌ๋ฌ๊ฐ์ ์ค์ฒฉ์ ์ธ ์ํฐํฐ๋ฅผ ์ต๋ํ ๊ฐ์ง์ง ์๊ฒ ์ค๊ณํด์ผ ํฉ๋๋ค.(์ด๊ทธ๋ฆฌ๊ฒ์ดํธ ์๋ ๊ฐ์ธ์ ์ผ๋ก ํ๊ฐ ์ ๋์ ์ํฐํฐ ์ค๊ณ๊ฐ ์ ์ ํ๋ค ์๊ฐํฉ๋๋ค.)๊ทธ๋ฐ ๊ตฌ์กฐ๋ฅผ ํผํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ์งํํฉ๋๋ค. 1. Aggregate Root ๊ธฐ์ค์ผ๋ก ์ค๊ณDDD์์๋ ํ Aggregate Root(Aggregate์ ์ต์์ ์ํฐํฐ)์์ ๋ค๋ฅธ Aggregate Root๋ฅผ ์ง์ ์ฐธ์กฐํ์ง ์๋๋ก ๊ถ์ฅํฉ๋๋ค.์ฆ, A -> B -> C ํํ๊ฐ ์๋๋ผ A๊ฐ B์ ID๋ง ๊ฐ๊ณ , B๊ฐ C์ ID๋ง ๊ฐ์ง๋๋ก ์ค๊ณํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.2. Lazy Loading์ ๋๋ฉ์ธ ๋ ์ด์ด์์ ์ง์ ๊ตฌํJPA์ Lazy Loading์ ์ฌ์ฉํ์ง ์๋๋ค๋ฉด, ์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.์๋ฅผ ๋ค์ด, A์์ B๋ฅผ ๊ฐ์ ธ์ฌ ๋, B์ ๋ฆฌ์คํธ๋ฅผ ๋ก๋ฉํ๋ ๊ฒ์ด ์๋๋ผ BRepository๋ฅผ ํตํด ํ์ํ ๋ ์กฐํํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค.class A { private List bIds; // ID๋ง ์ ์ฅ public List getBs(BRepository bRepository) { return bRepository.findAllByIds(bIds); } } ์ด๋ ๊ฒ ํ๋ฉด A๊ฐ B๋ฅผ ์ง์ ํฌํจํ์ง ์๊ณ ID๋ง ์ ์ฅํ์ฌ ํ์ํ ๋๋ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ๋ต๋ณ์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ, ๊ฐ์ฌํฉ๋๋ค.
- 0
- 2
- 110
Q&A
ํฅ์ฌ๊ณค ์ํคํ ์ณ ๊ด๋ จํ์ฌ ๋ฌธ์๋๋ฆฝ๋๋ค.
์๋ ํ์ธ์. ๊ฐ์์ ํ์ ํ์ ๋๋ค.ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ๋ ํฌํธ ์ ์ด๋ํฐ ํจํด์ ์ ์ํ alistair cockburn๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ํ ํํ์ ๋ชจ์ต์ผ๋ก ์๊ฐ๋๊ณ ์์ต๋๋ค.์ธ๊ธํ์ ๋ชจ๋ธ์ ์ธํฐ๋ท์ ์ผ๋ฐ์ ์ผ๋ก ๋ง์ด ํผ์ ธ ์์ผ๋ ์ํํธ์จ์ด ์ํคํ ์ฒ๊ฐ ๋ค์ํ ๋ณ์ข ์ด ์๊ณ ์ํฉ์ ๋ฐ๋ผ ์ฌ๋ฌ ๋ชจ๋ธ์ด ์์ ์ ์๋ค ์๊ฐํฉ๋๋ค.์ ๊ฐ ๊ฐ์ ์ ์ฐธ๊ณ ํ ๋ชจ๋ธ์ ๋ค๋น ๋น์์ด๋ผ์ 'ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ ์ค๊ณ์ ๊ตฌํ'์ด๋ผ๋ ์์ ์ ๋ชจ๋ธ์ ๋๋ค.ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ ๋ชจ๋ธ์ 3๊ฐ์ ํฅ์ฌ๊ณ ๋(๋๋ฉ์ธ,์ ํ๋ฆฌ์ผ์ด์ ,ํ๋ ์์ํฌ)๋ก ๋๋๊ณ ๊ฐ๊ฐ์ ์๋ฏธ๋ฅผ ๋ถ์ฌํ๋๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ํฅ์ฌ๊ณค์ ์์๋ฅผ ์ ์ค์ผ์ด์ค-์ธํํฌํธ-์์ํํฌํธ๋ก ๊ตฌํํ๊ณ ์ ์ค์ผ์ด์ค๋ฅผ ์ธํฐํ์ด์ค๋ก ์ ์ํ๊ณ ์ธํํฌํธ๋ฅผ ๊ตฌํ์ฒด๋ก ํ์ฉํ์ต๋๋ค.๋ค๋น ๋น์์ด๋ผ์ ๋ฐฉ์์ ์ ์ค์ผ์ด์ค๋ฅผ ๋จ์ํ ๊ตฌํ์ฒด์ ์ญํ ๋ณด๋ค๋์ด๋ฐ ์ผ์ฝ์จ์ '์ ์ค์ผ์ด์ค ์๋๋ฆฌ์ค, '์ ์ค์ผ์ด์ค ๋ช ์ธ' ์ ๊ฐ๋ ์ผ๋ก ํ์ ํ ๊ฒ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ํฅ์ฌ๊ณค์ด ๊ฐ๋ ์๋ฏธ ์ฆ '์์คํ ์ด ์ ์ ํ ๋ชฉํ๋ฅผ ๋ฌ์ฑํ๊ธฐ ์ํด ํจ๊ป ๋์ํ๋ ์ผ๋ จ์ ํ์์ ์งํฉ'๋ฅผ ๊ตฌํํ๋ค. ๋ฅผ ๊ฐ์กฐํ๊ธฐ ์ํด ์ ์ค์ผ์ด์ค๋ก ์ด๋ฌํ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ ๊ณตํ ๊ธฐ๋ฅ(์ผ๋ จ์ ํ์ ์งํฉ์ผ๋ก ์๋๋ฆฌ์ค ํํ์)๋ฅผ ๋จผ์ ์ธํฐํ์ด์ค๋ก ์ ์ํ ๊ฒ์ด๋ผ ์๊ฐํฉ๋๋ค.์ฆ ๊ฐ๋จํ ๋งํ๋ฉด, ์ ํ๋ฆฌ์ผ์ด์ ํฅ์ฌ๊ณค์์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ๋๋ฉ์ธ ํฅ์ฌ๊ณค์ด ๊ฐ์ง ๋น์ง๋์ค ์ฌ๋ฌ ๊ฐ๋ ์ ๋ณตํฉ์ ์ผ๋ก ํ์ฉํ์ฌ ๋น์ง๋์ค ๋ชฉ์ ์ ๋ง๋ ์๋๋ฆฌ์ค๋ฅผ ๊ตฌํํ๋ ๊ฒ์ธ๋ฐ, ๊ทธ๊ฑธ ๋ช ํํ ํํํ ๋ฐฉ์์ด ์ด๋ฐ ์ผ์ฝฅ์จ '์ ์ค์ผ์ด์ค ๋ช ์ธ'๋ผ๋ ๋ฐฉ์์ด๊ณ , ์ด๊ฒ์ ๊ฐ์กฐํ ๊ตฌ์กฐ๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.์ ๋ ์ด ๋ฐฉ์์ด ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ ๋ชจ๋ธ์ '์ ์ค์ผ์ด์ค' ๋ผ๋ ๊ฐ๋ ์ ์ค๋ช ํ๋๋ฐ ํ๋น ํ๋ค๊ณ ์๊ฐํ์ฌ ์ด ๋ฐฉ์์ผ๋ก ๊ฐ์๋ฅผ ๊ตฌ์ฑํ์์ต๋๋ค.๋ฌผ๋ก Management Uiti๋์ด ์ ์ํ์ ๊ตฌ์กฐ๋ก ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ ๊ตฌ์กฐ๋ฅผ ์ก์๋ ํ๋นํ๋ค๊ณ ์๊ฐํฉ๋๋ค. Management Uiti๋์ด ์ ์ํ์ ๊ตฌ์กฐ๋ ๋น์ง๋์ค์ ๊ธฐ์ ์ ์ด๋ป๊ฒ ๋ถ๋ฆฌํ์ฌ ์ด๋ป๊ฒ ์ ์ฐํ๊ฒ ํ ๊ฒ ์ธ๊ฐ? ์ ์ด์ ์ ๋ง์ท๋ค๋ฉด , ๋น์์ด๋ผ์ ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ๋ ํ ๋ฐ ๋ ๋์๊ฐ ๊ทธ๋ ๋ค๋ฉด ๋น์ง๋์ค ๊ฐ๋ ๊ณผ ํ๋์ ์ด๋ป๊ฒ ๊ตฌ์กฐํ ํ ๊ฒ์ธ๊ฐ๋ฅผ ์ข ๋ ์๊ฐํ ๊ฒฐ๊ณผ๋ผ ํ๋จ๋ฉ๋๋ค.๋ต๋ณ์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ ๊ฐ์ฌํฉ๋๋ค.
- 2
- 2
- 141
Q&A
๋ค๋ฅธ BC ๋๋ ๋ง์ดํฌ๋ก์๋น์ค ๋ด๋น ์ ๋ณด๋ฅผ ์ด๋ป๊ฒ ์ด์ฉํ๋์?
๊ฐ์์์ ๋๋ค.^ ^ AI๊ฐ ์ด๋ฏธ ๋ต๋ณ์ ๋๋ ธ๋ค์. AI ๊ฐ ๋งํ๋ฐ์ ๊ฐ์ด API,์ด๋ฒคํธ๊ธฐ๋ฐ ํต์ ,๋ฐ์ดํฐ ๋ณต์ ๋ก ํด๊ฒฐํ ์ ์์ผ๋ฉฐ, ์์ธ๋ก ๋ฐฑ์๋ ์๋น์ค๊ฐ์ ์ฐ๊ด๊ด๊ณ๋ณด๋ค๋ ํ๋ก ํธ์๋ ๋จ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ๊ฐ ์๋ ์์ต๋๋ค.์๋ฅผ ๋ค๋ฉด ๋์ฌ์๋น์ค๊ฐ ํ์ํ ๋์์ ๋ณด์ ์ฌ์ฉ์์ ๋ณด๋ฅผ ํ๋ก ํธ์ ์ด๋ฏธ ์กฐํ๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ๊ฐ ์ ์์ต๋๋ค. ๋ฌผ๋ก ๋ฐฑ์๋ ๋์ฌ ์๋น์ค์์ ์ค์ ์ฌ์ฉ์๊ฐ ์กด์ฌํ๋์ง? ์ ๋์๊ฐ ๋์ฌ๊ฐ๋ฅํ์ง์ ๋ํ ๊ฒ์ฆ์ ํ์ํฉ๋๋ค.์ดํ ๊ฐ์๋ฅผ ๋ ๋ฃ๋ค ๋ณด์๋ฉด ๋ ๊น์ ์ดํด๊ฐ ๊ฐ๋ฅํ์ค ๊ฒ์ด๋ผ ํ๋จ๋ฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
- 0
- 3
- 98
Q&A
VO ํด๋์ค์ ๋ถ๋ณ ํ๋ ์ ์ธ์ ํ์ง ์์ผ์ ์ด์ ?
๊ฐ์์ ํ์ ํ์ ๋๋ค.๋ต๋ณ๋๋ฆฌ๋ฉด ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ์์ vo๋ฅผ ์ค๊ณํ ๋ ๋ถ๋ณ์ฑ์ ์ ์งํ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํ ์์น ์ค ํ๋์ ๋๋ค. ๋ฐ๋ผ์ private final๋ก ํ๋๋ฅผ ์ ์ธํ์ฌ vo ๋ด๋ถ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ง ์๊ฒ ์์ ํ๊ฒ ํจ ์ข์ ์ค๊ณ ๋ฐฉ๋ฒ์ ๋๋ค. ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ฉด ๋ด๋ถ์์ ์ฌ์ฉํ๋ ๊ฐ์ฒด,List,Map๋ฑ์ด ์๋ค๋ฉด ์ด ๋ํ ๋ชจ๋ ๋ถ๋ณ์ผ๋ก ์ ์งํด์ผ ํ๊ณ ์ธ๋ถ ๊ฐ์ฒด ์ฐ๋ ์ ๋ถ๋ณ์ฑ์ ์ ์งํ๋ ์ฝ๋ ์์ฑ ๋ฑ ๊ฐ์ฒด ๋ด๋ถ์ ๋ณต์ก์ฑ์ด ์ฆ๊ฐํ๊ณ ์ถ๊ฐ ์ ์ธ ์ฒ๋ฆฌ ์ฝ๋ ์์ ์ด ํ์ํฉ๋๋ค. ๋ฐ๋ผ์ ๋ถ๋ณ์ฑ์ ์ ์งํ๋ ๊ฒ์ ์ค์์ฑ๊ณผ ๊ทธ๊ฒ์ ์ ์งํ๊ธฐ ์ํ ๋ณต์ก์ฑ ์ถ๊ฐ ๋ฑ์ ํธ๋ ์ด๋ ์คํ ํ ํ์์ฑ์ด ์์ต๋๋ค.๋ณธ ๊ฐ์์์๋ ์ด๋ฌํ ์ ์ ๊ณ ๋ คํ์ฌ ,ํนํ ๊ฐ๋ ์ฑ ์ธก๋ฉด์์ final์ฒ๋ฆฌํ์ง ์๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ rentalItem ์ ์ด์ ๋ชจ๋ธ๋ง ๊ฐ์ ์์ VO ๋ก ์ ์ธํ์ผ๋ overDued์ ๊ฐ์ด ๋ณ๊ฒฝ๋จ์ผ๋ก ๋ถ๋ณ์ฑ์ ์์์ผ๋ก์ ์ํฐํฐ๋ก ๋ค์ ๊ฐ๋ ์ ์ ํ ๋ถ๋ถ์ ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ํฐํฐ์์๋ @Entity ์ฒ๋ฆฌ๋ฅผ ์ ํ์ ์ ์ง์ ์ฃผ์ จ๋๋ฐ JPA์ @Entity์ ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ(DDD, Domain-Driven Design)์์์ ์ํฐํฐ(Entity)๋ ์๋ก ๋ค๋ฅธ ๋งฅ๋ฝ์์ ์ฌ์ฉ๋๋ ๊ฐ๋ ์ ๋๋ค. ๋ ๊ฐ๋ ๋ชจ๋ "์ํฐํฐ"๋ผ๋ ์ฉ์ด๋ฅผ ์ฌ์ฉํ์ง๋ง, ๋ชฉ์ ๊ณผ ์ด์ ์ด ๋ค๋ฆ ๋๋ค.DDD์ ์ํฐํฐ ์ํ์ ๋์ : ๋ฐ์ดํฐ๋ฟ๋ง ์๋๋ผ ํ์(๋ฉ์๋)๋ฅผ ํฌํจ์๋ณ์ฑ(์๋ณ์์ ๊ธฐ์ค์ผ๋ก ๋์ผ์ฑ ํ๋จ) JPA์ ์ํฐํฐ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋๊ธฐํ์ ๋ชฉ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋งคํ๋จ์ ์๋ฏธ๋ฐ๋์ ๊ธฐ๋ณธํค๊ฐ ์กด์ฌํด์ผ ํจ.(@id)๋ฌผ๋ก ํ์ค์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋งคํ์ JPA์ @Entity์ DDD์ ์ํฐํฐ๋ ํจ๊ป ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๊ทธ๋ ์ง๋ง ๋ฐ๋์ ๊ทธ๋์ผ๋ง ํ๋ ๊ฒ๋ ์๋๋๋ค.์ฆ ๋น์ง๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๋๋ฉ์ธ ๋ชจ๋ธ๋ง ๊ณผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ์ํ or๋งคํ๊ณผ๋ ์ ํ ๋ค๋ฅธ ์์ญ์ด๋ผ ์๊ฐํฉ๋๋ค.๋ฐ๋ผ์ RentalItem์ ๊ฒฝ์ฐ ์ด๊ธฐ์ ๋๋ฉ์ธ ๋ชจ๋ธ๋ง ๊ด์ ์์ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ vo๋ก ์ค๊ณํ์ผ๋ overdued๋ฑ์ ๊ฐ์ด ๋ณ๊ฒฝ๋์ด ๋ถ๋ณ์ฑ์ด ๊นจ์ง๋ค ํ๋จํ์ฌ ์ํฐํฐ๋ก ๊ฐ๋ ์ ๋ณ๊ฒฝํ ๊ฒ์ด์ง๋ง ์ญ์ vo์ ์ฑ๊ฒฉ์ด ๊ฐํ๊ธฐ ๋๋ฌธ์ vo์ฒ๋ผ ์ฒ๋ฆฌ ํ๋ค๊ณ ์๊ฐํ์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
- 0
- 2
- 177
Q&A
RentalCard ์ calculateLateFee ๋ฉ์๋ ๊ตฌํ์ด ์๋ชป๋ ๊ฒ ๊ฐ์ต๋๋ค.
tkwoo๋ ์๋ ํ์ธ์. ๊ฐ์์์ ๋๋ค.๋ค ์ง์ ํ์ ์ ์ด ๋ง์ต๋๋ค. ์ ๊ฐ ์ฝ๋์ ๊ฒฐํจ์ ์ธ์งํ๊ณ ์ ๊ณตํ๋ ์์ค์ฝ๋์๋ ์ดํ ๋ณ๊ฒฝํ์๋๋ฐ, ๋์์ ์์๋ ๊ณต์ง๋ฅผ ์ ๋๋ก ํ์ง ๋ชปํ๋ค์. ์ฃ์กํฉ๋๋ค. ๋ค์ ํ์ธํด์ ๊ณต์ง๋ฅผ ํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ง์ ๊ฐ์ฌํฉ๋๋ค.
- 1
- 2
- 138
Q&A
20๋ถ์ ๋์ ๋ง์ ํ์ ๋ด์ฉ ์ง๋ฌธ ์์ต๋๋ค.
์ ์ํคํ ์ฒ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ๊ฐ๋ ์ ์ธ ์ฉ์ด๋ค์ ์ฌ์ฉํ์ง๋ง ์ด๋ฐ ๊ธฐ๋ฅ์ ์นดํ์นด ๋งค์ปค๋์ฆ์ด ์ด๋ฏธ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ๋จํ ๊ตฌํํด ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ฃผ๋ฌธ ์๋น์ค๊ฐ ์๋ก์ด ์ฃผ๋ฌธ์ ์์ฑํ๋ฉด, ์ด ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ Kafka์ ์ด๋ฒคํธ๋ก ๋ณด๋ด๊ณ , ์ฃผ๋ฌธ ์ด๋ ฅ ์๋น์ค๊ฐ ์ด ์ด๋ฒคํธ๋ฅผ ์ฝ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฃผ๋ฌธ ์ด๋ ฅ์ ์ ์ฅํ ํ, ๋ฉ์์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋์์์ ํ์ธํ๊ณ Kafka์์ ํด๋น ๋ฉ์์ง๋ฅผ ์ ๊ฑฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.์๋๋ ์ด ๊ณผ์ ์ ๊ฐ๋จํ ์ํ ์ฝ๋์ ํจ๊ป ์ค๋ช ํ๊ฒ ์ต๋๋ค.1. Kafka์ ์ฃผ๋ฌธ ์ด๋ฒคํธ ๋ณด๋ด๊ธฐ (์ฃผ๋ฌธ ์๋น์ค)์ฃผ๋ฌธ ์๋น์ค๊ฐ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ Kafka์ ๋ณด๋ด๋ ๊ณผ์ ์ ๋๋ค. Python์ kafka-python ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ Kafka์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ์์ ์ ๋๋ค.from kafka import KafkaProducer import json # Kafka ํ๋ก๋์ ์ค์ producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) # ์ฃผ๋ฌธ ๋ฐ์ดํฐ order = { 'order_id': '12345', 'customer_id': '67890', 'amount': 100.0 } # Kafka ํ ํฝ์ ์ฃผ๋ฌธ ์ด๋ฒคํธ ์ ์ก producer.send('order-topic', order) producer.flush()2. ์ฃผ๋ฌธ ์ด๋ ฅ ์ ์ฅ ๋ฐ Kafka ๋ฉ์์ง ์ญ์ (์ฃผ๋ฌธ ์ด๋ ฅ ์๋น์ค)์ฃผ๋ฌธ ์ด๋ ฅ ์๋น์ค๊ฐ Kafka์์ ๋ฉ์์ง๋ฅผ ์ฝ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๊ณ , ์ ์ฅ์ด ์๋ฃ๋๋ฉด Kafka์์ ํด๋น ๋ฉ์์ง๋ฅผ ์ ๊ฑฐํฉ๋๋ค. Python์ kafka-python๊ณผ mysql-connector-python์ ์ฌ์ฉํ ์์ ์ ๋๋ค.from kafka import KafkaConsumer, KafkaProducer import mysql.connector import json # Kafka ์ปจ์๋จธ ์ค์ consumer = KafkaConsumer( 'order-topic', bootstrap_servers='localhost:9092', auto_offset_reset='earliest', group_id='order-history-group', value_deserializer=lambda x: json.loads(x.decode('utf-8')) ) # Kafka ํ๋ก๋์ ์ค์ producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode('utf-8') ) # MySQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ db_conn = mysql.connector.connect( host='localhost', user='youruser', password='yourpassword', database='yourdatabase' ) cursor = db_conn.cursor() # Kafka ๋ฉ์์ง ์ฒ๋ฆฌ for message in consumer: order = message.value order_id = order['order_id'] customer_id = order['customer_id'] amount = order['amount'] # ์ฃผ๋ฌธ ์ด๋ ฅ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ cursor.execute( "INSERT INTO OrderHistory (order_id, customer_id, amount) VALUES (%s, %s, %s)", (order_id, customer_id, amount) ) db_conn.commit() # ๋ฉ์์ง ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ ํ Kafka์์ ๋ฉ์์ง ์ญ์ (offset ์ปค๋ฐ) consumer.commit() # ๋ฉ์์ง ์ ์ก ์ํ๋ฅผ ํ์ธํ๊ณ ๋ก๊ทธ ๊ธฐ๋ก ๋๋ ๋ค๋ฅธ ์์ ์ํ print(f"Order {order_id} processed and saved to database.") ์ฝ๋ ๋ณต์ฌ์์ฝ์ฃผ๋ฌธ ์๋น์ค: ์ฃผ๋ฌธ์ Kafka ํ ํฝ์ ๋ฉ์์ง๋ก ์ ์กํฉ๋๋ค.์ฃผ๋ฌธ ์ด๋ ฅ ์๋น์ค:Kafka์์ ๋ฉ์์ง๋ฅผ ์ฝ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฃผ๋ฌธ ์ด๋ ฅ์ ์ ์ฅํฉ๋๋ค.๋ฉ์์ง๋ฅผ ์ฒ๋ฆฌํ ํ Kafka์ ์คํ์ ์ ์ปค๋ฐํ์ฌ ๋ฉ์์ง๊ฐ ๋ ์ด์ ์ฒ๋ฆฌ๋์ง ์๋๋ก ํฉ๋๋ค.์๋ฐํ ๋งํ๋ฉด Kafka์์ ์คํ์ (offset)์ ํน์ ํํฐ์ ๋ด์์ ๋ฉ์์ง์ ์์น๋ฅผ ๋ํ๋ ๋๋ค. ์ฆ ์๋น์๊ฐ ๋ฉ์์ง๋ฅผ ์ฒ๋ฆฌํ ํ, Kafka์ ์ปจ์๋จธ ๊ทธ๋ฃน์ ํด๋น ๋ฉ์์ง๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋์๋ค๋ ๊ฒ์ ๋ํ๋ด๊ธฐ ์ํด ์คํ์ ์ ์ปค๋ฐํฉ๋๋ค. ์คํ์ ์ปค๋ฐ์ Kafka๊ฐ ๋ฉ์์ง๋ฅผ ์ด๋ ์ง์ ๊น์ง ์ฝ์๋์ง๋ฅผ ๊ธฐ๋กํฉ๋๋ค. ์ฆ, ์ปจ์๋จธ๊ฐ ๋ค์์ ์ฌ์์๋ ๋, ๋ง์ง๋ง์ผ๋ก ์ปค๋ฐ๋ ์คํ์ ๋ถํฐ ๋ฉ์์ง๋ฅผ ์ฝ๊ธฐ ์์ํฉ๋๋ค. ๋ฐ๋ผ์ ํ๋ฒ ์ ๋ฌ๋ ๋ฉ์์ง๊ฐ ๋ค์ ์ ๋ฌ๋์ง ์์์ ๋ณด์ฅํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์นดํ์นด์ ๋ฉ์์ง๋ ์นดํ์นด ๋ก๊ทธ ๋ณด์กด๊ธฐ๊ฐ์ ๋ฐ๋ผ ์๋์ผ๋ก ์ญ์ ๋๊ฒ ํ๋ฉด ๋ฉ๋๋ค.
- 0
- 2
- 196







