ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

Spring ์Šคํ„ฐ๋””๋ฅผ 5์ฃผ๊ฐ„ ์ง„ํ–‰ํ•˜์˜€๋‹ค. ์ฝ”๋ฆฐ์ด์ธ ๋‚˜๋Š” ๋‚œ์ด๋„๊ฐ€ ๋ชน์‹œ ์–ด๋ ต๊ณ  ๋”ฐ๋ผ๊ฐ€๊ธฐ ๋ฒ…์ฐผ๋˜ ์Šคํ„ฐ๋””์˜€๋‹ค. ๊ทธ๋ž˜๋„ ์•Œ๊ฒŒ๋œ๊ฒƒ๋„ ๋งŽ์ด ์žˆ๊ณ  ๋‚ด๊ฐ€ ์•Œ๋˜๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅธ ๋‚ด์šฉ๋„ ์žˆ์–ด์„œ ํ•˜๊ธธ ์ž˜ํ–ˆ๋‹ค๋Š” ์ƒ๊ฐ์ด๋“ ๋‹ค. ๊ด€๋ จ ์ฐธ๊ณ  ์ž๋ฃŒ๋ฅผ ์šฐ์„  ๋‹ค ์ €์žฅํ•ด๋‘๊ณ  ํ•˜๋‚˜ ํ•˜๋‚˜ ๋‹ค์‹œ ๋ณด๋„๋ก ํ•  ๊ฒƒ์ด๋‹ค.

 

Restful API

DDD building blocks

[DDD, Part 2: DDD Building Blocks](https://dzone.com/articles/ddd-part-ii-ddd-building-blocks)

[DDD(Domain Driven Design) - ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„๋ž€?](https://huisam.tistory.com/entry/DDD)

**DDD ๊ตฌ์„ฑ์š”์†Œ**

  1. Entities

    ์—”ํ‹ฐํ‹ฐ๋Š” id๊ฐ€ ์žˆ๊ณ  ์ž ์žฌ์ ์œผ๋กœ ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•œ ์ผ๋ฐ˜ ๊ฐ์ฒด์ด๋‹ค. ๊ฐ ์—”ํ‹ฐํ‹ฐ๋Š” ์†์„ฑ์ด ์•„๋‹Œ ID๋กœ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์†์„ฑ์ด ๋‹ค๋ฅด๋”๋ผ๋„ ๋™์ผํ•œ ID๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ๋‘ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋™์ผํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ ๋  ์ˆ˜ ์žˆ๋‹ค.(์‹๋ณ„์ž ๋™์ผ์„ฑ) ์ฆ‰, ์—”ํ‹ฐํ‹ฐ์˜ ์ƒํƒœ๋Š” ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‘ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๋™์ผํ•œ ID๋ฅผ ๊ฐ–๋Š” ๋‘ ์—”ํ‹ฐํ‹ฐ๋Š” ์–ด๋–ค ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€์— ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋œ๋‹ค.

  2. Value Objects

    VO๋Š” ๋ถˆ๋ณ€ํ•˜๋‹ค. VO๋Š” ์—”ํ‹ฐํ‹ฐ์—์„œ ๋ณผ์ˆ˜์žˆ๋Š” ID๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค. ๋‘ ๊ฐœ์˜ VO๊ฐ€ ๋™์ผํ•œ ํƒ€์ž…๊ณผ ๊ฐ™์€ ์†์„ฑ(๋ชจ๋“  ์†์„ฑ์— ์ ์šฉ๋จ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋™์ผํ•œ ๊ฐ์ฒด๋กœ ๊ฐ„์ฃผ๋  ์ˆ˜ ์žˆ๋‹ค.

    ์ข…์ข… ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ๊ณผ ๊ฐ™์€ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ ์‹ค์ œ๋กœ ์ด๋Š” ๋ถˆ๋ณ€์˜ ์ธก๋ฉด์„ ๋ฐ˜๋“œ์‹œ ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋„๋ฉ”์ธ ๊ฐœ๋…์„ ๋…ธ์ถœํ•˜๋Š” ์–‘ํŒŒ ์•„ํ‚คํ…์ฒ˜ ๋‚ด์˜ API๊ณ„์ธต์—์„œ ํŠนํžˆ ์œ ์šฉํ•˜๋‹ค.

    [์–‘ํŒŒ์•„ํ‚คํ…์ฒ˜๊ฐ€ ๋ญ”์ง€ ๋ชฐ๋ผ์„œ ๊ฒ€์ƒ‰](https://dev.to/barrymcauley/onion-architecture-3fgl)

    VO์˜ ์ด์  :

    • VO์˜ ๋ณตํ•ฉ์€ ๋งŽ์€ ๊ณ„์‚ฐ ๋ณต์žก์„ฑ์„ ์‚ผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

    • ์—”ํ‹ฐํ‹ฐ๋Š” ๋…ผ๋ฆฌ ๋ณต์žก์„ฑ์—์„œ ํ•ด์ œ ๋  ์ˆ˜ ์žˆ๋‹ค.

    • ํŠนํžˆ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ…Œ์ด์Šค ๊ฐ€๋Šฅ์„ฑ ๋ฐ ๋™์‹œ์„ฑ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ™•์žฅ์„ฑ์„ ๊ฐœ์„ ํ•œ๋‹ค.

  3. Aggregate Roots

    Aggregate Roots๋Š” ๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ์™€ ํ•จ๊ป˜ ๊ฒฐํ•ฉํ•˜๋Š” ์—”ํ‹ฐํ‹ฐ์ด๋‹ค. ๋˜ํ•œ Aggregate Roots๋Š” ์‹ค์ œ๋กœ ์ง‘๊ณ„์˜ ์ผ๋ถ€์ด๋‹ค.(๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์œ„ํ•ด ๋‹จ์ผ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ด€๋ จ ๊ฐœ์ฒด์˜ ์ปฌ๋ ‰์…˜/ํด๋Ÿฌ์Šคํ„ฐ) ๋”ฐ๋ผ์„œ ๊ฐ ์ง‘๊ณ„๋Š” ์‹ค์ œ๋กœ ์ง‘๊ณ„๋ฃจํŠธ์™€ ๊ฒฝ๊ณ„๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, SalesOrderDomain ๋‚ด์˜ Order์™€ OrderLineItem ๊ฐ„์˜ ๊ด€๊ณ„๋Š” Order๊ฐ€ ์ง‘๊ณ„ ๋ฃจํŠธ ์—ญํ• ์„ ํ•˜๋Š” ์ง‘๊ณ„๋กœ ๊ฐ„์ฃผ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ OrderLineItem์€ SalesOrder ๊ฒฝ๊ณ„ ๋‚ด์—์„œ Order์˜ ํ•˜์œ„ ํ•ญ๋ชฉ์ด๋‹ค.

    ์ง‘๊ณ„ ๋ฃจํŠธ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋Š” ์™ธ๋ถ€ ๊ฐœ์ฒด๊ฐ€ ์ง‘๊ณ„ ๋ฃจํŠธ ์ž์‹ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ๋ณด์œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ง‘๊ณ„ ๋ฃจํŠธ ํ•˜์œ„ ํ•ญ๋ชฉ (aka ์ง‘๊ณ„) ์ค‘ ํ•˜๋‚˜์— ์•ก์„ธ์Šคํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ง‘๊ณ„ ๋ฃจํŠธ๋ฅผ ๊ฑฐ์ณ์•ผํ•œ๋‹ค.(์ฆ‰, ํ•˜์œ„ ํ•ญ๋ชฉ์— ์ง์ ‘ ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์—†์Œ)

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

  4. Repositories

    ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ์ฃผ๋กœ ์ €์žฅ์†Œ๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์‹ค์ œ๋กœ DDD์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ๋งŽ์€ ์ €์žฅ์†Œ ๋ฌธ์ œ(์˜ˆ : ์Šคํ† ๋ฆฌ์ง€ ์ผ๋ถ€ ํ˜•์‹/๋ฉ”์ปค๋‹ˆ์ฆ˜)๋ฅผ ์ถ”์ƒํ™” ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๊ตฌํ˜„์€ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์ €์žฅ์†Œ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(SQL / NoSQL๊ธฐ๋ฐ˜) ๋˜๋Š” ์บ์‹ฑ๊ณผ ๊ฐ™์€ ์ €์žฅ์†Œ ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ๊ด€๋ จ๋œ ๊ธฐํƒ€ ํ•ญ๋ชฉ์ผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋“ค์€ ๋ชจ๋“  ์กฐํ•ฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

    ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ์ €์žฅ์†Œ์™€ ํ˜ผ๋™ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. ๋ ˆํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ํ•˜๋Š” ์ผ์€ agrregate roots๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ ์•„๋ž˜์—์„œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๊ตฌํ˜„์€ ์ง‘๊ณ„๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‹ค์ œ๋กœ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์ €์žฅ์†Œ ์œ„์น˜์™€ ํ†ต์‹ ํ•ด์•ผํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹จ์ผ ์ง‘๊ณ„ ๋ฃจํŠธ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” ํŒŒ์ผ๋ฟ ์•„๋‹ˆ๋ผ REST API์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์— ๋ž˜ํ•‘ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ๋ชจ๋“  ๊ฐœ๋ณ„ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ์œ„์— ์ถ”๊ฐ€ ๋œ ์ถ”์ƒํ™” ๊ณ„์ธต์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ์–‘ํŒŒ ์•„ํ‚คํ…์ฒ˜ ๋‚ด ๋„๋ฉ”์ธ/๋„๋ฉ”์ธ ์„œ๋น„์Šค ๊ณ„์ธต ๋‚ด์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ตฌํ˜„ํ•œ ๋‹ค์Œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ๋…ผ๋ฆฌ๋ฅผ ์ธํ”„๋ผ ๊ณ„์ธต์—์„œ ์ •์˜ํ•œ๋‹ค.

  5. Factories

    ํŒฉํ† ๋ฆฌ๋Š” ๊ฐ์ฒด ๊ตฌ์„ฑ์— ์ถ”์ƒํ™”๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ([GOF์˜ ํŒฉํ† ๋ฆฌ ๋””์ž์ธ ํŒจํ„ด](Aggregate Roots))

    ํŒฉํ† ๋ฆฌ๋Š” ์ž ์žฌ์ ์œผ๋กœ ์ง‘๊ณ„ ๋ฃจํŠธ๋‚˜ ์—”ํ‹ฐํ‹ฐ ๋˜๋Š” VO๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ข…์ข… ์ง‘๊ณ„ ๋ฃจ์ธ ์— ๋Œ€ํ•œ ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ €์žฅ์†Œ๋กœ ๋กค๋ง๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์ €์žฅ์†Œ์—๋Š” ํŒŒ์ธ๋” ์ƒ์„ฑ ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

    ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌํ˜„ ๋…ผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„๋ฉ”์ธ/๋„๋ฉ”์ธ ์„œ๋น„์Šค ๊ณ„์ธต ๋‚ด์—์„œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ตฌํ˜„ ๋œ ๊ณต์žฅ๋„ ์ธํ”„๋ผ ๊ณ„์ธต์—์„œ ์ •์˜๋œ๋‹ค.

  6. Services

    ์„œ๋น„์Šค๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง‘๊ณ„ ๋ฃจํŠธ์— ๋งž์ง€ ์•Š๋Š” ์ž‘์—…์„ ์œ„ํ•œ ํ™ˆ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ž‘์—…์ด ์žˆ๊ณ  ์–ด๋–ค ์ง‘๊ณ„ ๋ฃจํŠธ๋กœ ๋“ค์–ด๊ฐ€๋Š”์ง€ ๋ชจ๋ฅผ ๋•Œ ์—ฌ๋Ÿฌ ์ง‘๊ณ„ ๋ฃจํŠธ์—์„œ ์ž‘๋™ํ•˜๊ณ ๋‚˜ ๊ธฐ์กด ์ง‘๊ณ„ ๋ฃจํŠธ์— ์†ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋…ผ๋ฆฌ๋ฅผ ์„œ๋น„์Šค์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๊ฒƒ์„ ์„œ๋น„์Šค์—์„œ ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๋ฌด์—‡๋ณด๋‹ค๋„ ์ž‘์—…์ด ๊ธฐ์กด ์ง‘๊ณ„ ๋ฃจํŠธ ์ค‘ ํ•˜๋‚˜์— ์ ํ•ฉํ•œ์ง€ ์‹ ์ค‘ํ•˜๊ฒŒ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ง‘๊ณ„ ๋ฃจํŠธ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ์ง‘๊ณ„ ๋ฃจํŠธ ํ•˜๋‚˜๋ฅผ ๋†“์ณค๋Š”์ง€ ์Šค์Šค๋กœ์—๊ฒŒ ๋ฌผ์–ด๋ณด๋Š”๊ฒƒ์ด ์ข‹๋‹ค. ์•„๋‹ˆ๋ฉด ์ž‘์—…์„ ๋„๋ฉ”์ธ์— ๊ฐ€์ ธ์˜ค๊ธฐ ์ „์— ๋„๋ฉ”์ธ์œผ๋กœ ๊ฐ€์ ธ์™€์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š” ๋„๋ฉ”์ธ ๊ฐœ๋…์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

**๊ธฐํƒ€ ์ค‘์š”ํ•œ ์‚ฌํ•ญ**

![img](https://cdn-images-1.medium.com/max/1600/1*-PJWpAFq29uDEqJt0zMrDQ.png)

VO ๋ฐ DTO๋Š” POJO / POCO์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด๋‹ค. ์—”ํ‹ฐํ‹ฐ๋Š” ๋˜ํ•œ POJO / POCO์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด๋‹ค. ์œ„์˜ ๋ฌ˜์‚ฌ์—์„œ POJO์™€ POCO๋Š” ์„œ๋กœ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‘˜ ๋‹ค ๋น„์Šทํ•œ ๊ฒƒ์„ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ๋‹ค. ๋‘˜ ๋‹ค ๋น„์ฆˆ๋‹ˆ์Šค ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ์ฃผ๋กœ ๋„๋ฉ”์ธ / ๋น„์ฆˆ๋‹ˆ์Šค ๊ฐœ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋„๋ฉ”์ธ ๊ฐœ์ฒด์ด๋‹ค.

POJO (plain old Java object)๋ผ๋Š” ์šฉ์–ด๋Š” Martin Fowler๊ฐ€ ๋งŒ๋“  ๊ฒƒ์œผ๋กœ Java ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋งค์šฐ ์ธ๊ธฐ๊ฐ€์žˆ๋Š” ๋ฐ˜๋ฉด POCO (plain old CLR object / plain old class object)๋Š” dotNet์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋œ๋‹ค.

์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด DTO, VO ๋ฐ ์—”ํ‹ฐํ‹ฐ๋Š” POJO / POCO์˜ ํ•˜์œ„ ์ง‘ํ•ฉ ์ผ๋ฟ์ด์ง€๋งŒ ์•„๋ž˜์— ์„ค๋ช… ๋œ๋Œ€๋กœ ์‹ค์ œ๋กœ๋Š” ๋‹ค๋ฅด๋‹ค.

![img](https://cdn-images-1.medium.com/max/1600/1*gLLWywd76Tg_poJ0aiWalg.png)

DTO๋Š” ๋ฉ์ฒญํ•œ ๋ฐ์ดํ„ฐ ์ปจํ…Œ์ด๋„ˆ์ด๋‹ค(๋กœ์ง์—†์ด ์˜ค์ง ๋ฐ์ดํ„ฐ๋งŒ ๋“ค๊ณ ์žˆ์Œ). ๋”ฐ๋ผ์„œ ์ผ๋ฐ˜์ ์œผ๋กœ ๋นˆํ˜ˆ์ด๋‹ค(์†์„ฑ ๋ฐ getter/setter๋งŒ ํฌํ•จ). DTO๋Š” ์ ˆ๋Œ€์ ์œผ๋กœ ๋ถˆ๋ณ€์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ DTO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ๋‹จ์ผ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๊ณ„์ธต๊ณผ ๊ณ„์ธต๊ฐ„์— ๋˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ๋˜๋Š” JVM์—์„œ JVM(๋‹ค์ค‘ ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋„คํŠธ์›Œํฌ๊ฐ„์— ๊ฐ€์žฅ ์œ ์šฉํ•จ)๊ฐ„์— ๊ฐœ์ฒด๋ฅผ ์ „์†กํ•œ๋‹ค.

VO ๋˜ํ•œ ๋ถˆ๋ณ€์ด์ง€๋งŒ DTO์™€ ๋‹ค๋ฅธ์ ์€ VO์—๋Š” ๋…ผ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

DTO(Data Transfer Object) & VO (Value Object)

[์˜์–ด๋กœ ๋œ ์„ค๋ช… DTO](https://martinfowler.com/eaaCatalog/dataTransferObject.html)

[์˜์–ด๋กœ ๋œ ์„ค๋ช… VO](https://martinfowler.com/eaaCatalog/dataTransferObject.html)

[DTO vs VO](https://multifrontgarden.tistory.com/182)

[final ํ‚ค์›Œ๋“œ ๋ถˆ๋ณ€ ์ •์˜](https://www.schibsted.pl/blog/immutability-entities-and-value-objects/)

[๊น”๋”ํ•˜๊ฒŒ DTO ๊ด€๋ฆฌํ•˜๊ธฐ](https://velog.io/@p4rksh/Spring-Boot%EC%97%90%EC%84%9C-%EA%B9%94%EB%81%94%ED%95%98%EA%B2%8C-DTO-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0)

  • DTO๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด์šฉ์€ ๋ชจ๋‘ **์ปจํŠธ๋กค๋Ÿฌ**์— ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  • ์„œ๋น„์Šค๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค์—์„œ๋„ ํ˜ธ์ถœ ๋  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋„๋ฉ”์ธ ๊ฐ์ฒด๋“ค์ด ์‚ฌ์šฉ๋˜์–ด์•ผํ•œ๋‹ค. ์„œ๋น„์Šค์—์„œ๋Š” DTO๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด๋“ค์ธ Entity, VO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

  • DTOํด๋ž˜์Šค์— SETTER๋ฅผ ๋‘์–ด๋„ ์ƒ๊ด€์ด ์—†์ง€๋งŒ ๋ถˆ๋ณ€์ด ๊ฐ€๋Šฅํ•˜๋ฉด ๋ถˆ๋ณ€์œผ๋กœ ํ•ด์ค€๋‹ค.

  • ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์„ ์œ„ํ•ด DTO๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์™€ Map์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ๊ฐ๊ฐ ์žฅ๋‹จ์ ์ด ์žˆ์Œ

    • DTO๋Š” ๋”์šฑ ๋ช…์‹œ์ ์ธ ์žฅ์ ์€ ์žˆ์ง€๋งŒ, class๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ๋‹จ์ 

    • Map์€ ์ถ”๊ฐ€์ ์ธ class๊ฐ€ ํ•„์š”์—†์ง€๋งŒ, ์ฃผ์„ ๋“ฑ์„ ํ†ตํ•ด ํŒŒ์•…์ด ์‰ฝ๋„๋ก ์ž˜ ๋ช…์„ธ๋ฅผ ํ•ด๋†“์•„์•ผ ํ•จ

  • Response DTO

    • ์–ด๋– ํ•œ ํƒ€์ž…๋„ ๋‹ด์„ ์ˆ˜ ์žˆ๋„๋ก ์ œ๋„ค๋ฆญ ์ฒ˜๋ฆฌํ•˜์ž

    • ์ด ํด๋ž˜์Šค์˜ ์—ญํ• ์ด ๋ฌด์—‡์ธ์ง€, ๋ฌด์Šจ ์ •๋ณด๋ฅผ ๋‹ด์•„์•ผํ• ์ง€ ์ƒ๊ฐํ•˜๊ธฐ ๋ชจ๋“  api์˜ ์‘๋‹ต์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋ง๊ณ  -> ์ด๊ฒŒ ๋ฌด์Šจ ๋ง์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค,,

    • ResponseDTO๋Š” ๋ณดํ†ต code(์ƒํƒœ ์ฝ”๋“œ), message(๋ฉ”์„ธ์ง€), data(์ „๋‹ฌ ๋ฐ์ดํ„ฐ)๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

    • ์ƒ์„ฑ์ž์™€ ResponseDto๋ฅผ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ๋ฉ”์†Œ๋“œ, Getter๋ฅผ ๋งŒ๋“ค์–ด ์ค€๋‹ค. Setter๋Š” ๋งŒ๋“ค์ง€ ์•Š์Œ(๋ถˆ๋ณ€์ด๊ธฐ ๋•Œ๋ฌธ์—)

DAO์™€ Repository

[DAO์™€ Repository์˜ ์ฐจ์ด์ ](https://stackoverflow.com/questions/8550124/what-is-the-difference-between-dao-and-repository-patterns)

๋นŒ๋” ํŒจํ„ด

[๋นŒ๋” ๋””์ž์ธ ํŒจํ„ด์œผ๋กœ ๋ถˆ๋ณ€์„ฑ ๋‹ฌ์„ฑ](https://dzone.com/articles/immutability-with-builder-design-pattern)

[๋กฌ๋ณต - @Builder ์–ด๋…ธํ…Œ์ด์…˜](https://www.baeldung.com/lombok-builder)

Lambda ํ‘œํ˜„์‹

[Java 8 Lambda ํ‘œํ˜„์‹ ์˜ˆ์ œ](https://www.byteslounge.com/tutorials/java-8-lambda-expressions-example)

Spring JDBC

`Spring JDBC`๋ž€ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๋ชจ๋“ˆ์ด๋‹ค. ๋‹จ์ˆœํ•˜๊ฒŒ DB CRUD์™ธ์—๋„ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ, ์ ‘๊ทผ ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

`๋ฐ์ดํ„ฐ ์†Œ์Šค`๋ž€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด DB์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•˜ ์ถ”์ƒํ™”๋œ ์—ฐ๊ฒฐ ๋ฐฉ์‹, ์ฆ‰ ์ปค๋„ฅ์…˜ (java.sql.connection)์„ ์ œ๊ณตํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๋…€์„์„ ์ง€์นญํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ์„ธ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

  • **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ชจ๋“ˆ์ด ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค**

    Commons DBCP, Tomcat JDBC Connection Pool๊ณผ ๊ฐ™์ด ์„œ๋“œํŒŒํ‹ฐ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค ํ˜น์€ DriverManagerDataSource ๊ฐ™์ด ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํ…Œ์ŠคํŠธ ์šฉ๋„๋กœ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

  • **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค** ์„œ๋ฒ„๊ฐ€ ์ •์˜ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ JNDI(Java Namming and Directory Interface)๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

  • **๋‚ด์žฅํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค**

    H2 ๊ฐ™์€ ๋‚ด์žฅํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ ์Šคํ”„๋ง JDBC์™€ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ์ž‘์—…์„ application.properties ์— ์ž‘์„ฑํ•˜๋ฉด๋œ๋‹ค.

Spring JDBC๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณตํ†ต์ ์ด๊ณ  ๋ฐ˜๋ณต๋˜๋Š” ์ž‘์—…์„ ๋Œ€์‹ ํ•ด์ค€๋‹ค๋Š” ์ด์ ์ด ์žˆ๋‹ค.

  • ์ปค๋„ฅ์…˜์˜ ์—ฐ๊ฒฐ๊ณผ ์ข…๋ฃŒ

  • SQL ๋ฌธ์˜ ์‹คํ–‰

  • SQL ๋ฌธ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ ํ–‰์— ๋Œ€ํ•œ ๋ฐ˜๋ณต ์ฒ˜๋ฆฌ

  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๋Š” SQL๋ฌธ์˜ ์ •์˜, ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •, SQL์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ๋ ˆ์ฝ”๋“œ ๋ณ„๋กœ ํ•„์š”ํ•œ ์ฒ˜๋ฆฌ๋งŒ ํ•˜๋ฉด๋œ๋‹ค.

Spring JDBC๋Š” Jdbc Template๋ผ๋Š” ํด๋ž˜์Šค๋กœ ๋ฐ์ดํ„ฐ CRUD ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

**Jdbc Template CRUD ์ž‘์—… ์‹œ ์ฃผ์š” ๋ฉ”์„œ๋“œ**

๋ฉ”์†Œ๋“œ๋ช…์„ค๋ช…

queryForObject ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ ๋ ˆ์ฝ”๋“œ ์ค‘ ํ•˜๋‚˜์˜ ์นผ๋Ÿผ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉ, RowMapper ๋“ฑ๊ณผ ๋งคํ•‘์„ ๋„์™€์ฃผ๋Š” ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉฐ ๊ฐ์ฒด์— ๋งคํ•‘, ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋‘๊ฐœ ์ด์ƒ์ด๋ฉด ์˜ˆ์™ธ (IncorrectResultSizeDataAccessException)์„ ๋ฐœ์ƒ์‹œํ‚ด, ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋งคํ•‘ํ•  RowMapper ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋“œ์‹œ ์ง€์ •ํ•ด์•ผํ•จ
queryForMap ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ ๋ ˆ์ฝ”๋“œ ์ •๋ณด๋ฅผ Map ํ˜•ํƒœ๋กœ ๋งคํ•‘
queryForList ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฒฐ๊ณผ ๋ ˆ์ฝ”๋“œ๋ฅผ List๋กœ Map<String, Object> ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜
query ResultSetExtractor, RowCallbackHander์™€ ๊ฐ™์ด ์‚ฌ์šฉ, ์‹คํ–‰๊ฒฐ๊ณผ๊ฐ€ List<T>์ผ ๋•Œ ์‚ฌ์šฉ
update ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” SQL INSERT, DELETE, UPDATE๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ

https://m.blog.naver.com/adamdoha/222078797274

https://velog.io/@sa833591/Repository-Jdbc-%EC%B2%98%EB%A6%AC-%EC%BD%94%EB%93%9C-%EA%B5%AC%ED%98%84

[baeldung Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate)

JDBC Template

JDBC datasource ์„ค์ •

  • application.properties์— db ๊ด€๋ จ ์„ค์ •์„ ์•ˆํ•ด์ฃผ๋ฉด Failed to configure a DataSource ์–ด์ฉŒ๊ณ  ํ•˜๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์„ค์ •์„ ํ•ด์ค„ ๊ฒƒ

KeyHolder & PerparedStatement

jdbcTemplate.update()๋กœ ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋™์‹œ์— ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ์˜ key๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ

Spring MVC

[baeldung](https://www.baeldung.com/spring-mvc-tutorial)

[Spring Docs](https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html)

Spring Message Source

[baeldung message source](https://www.baeldung.com/spring-custom-validation-message-source)

Validation

[์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฐ€์ด๋“œ](https://reflectoring.io/bean-validation-with-spring-boot/)

[baeldung Validation](https://www.baeldung.com/spring-boot-bean-validation)

Spring unit Testing

[์Šคํ”„๋ง docs test](https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testing-introduction)

Spring MVC Test

[์›น๋ ˆ์ด์–ด ํ…Œ์ŠคํŠธ - JUnit](https://spring.io/guides/gs/testing-web/)

[์Šคํ”„๋ง MVC ๋‹จ์œ„ ํ…Œ์ŠคํŠธ Junit](https://thswave.github.io/java/2015/03/02/spring-mvc-test.html)

ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์„ ๋งŽ์ด ํ•ด๋ณด๋Š” ์—ฐ์Šต์„ ํ•˜๋ผ

mock

ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋‹ค๊ฐ€ ์‹คํŒจ๋ฅผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋””๋ฒ„๊น…์„ ํ•ด์•ผ์ง€

์›ํ•˜๋Š” ๊ฒฐ๊ณผ๊ฐ’์ด ๋‚˜์˜ค์ง€ ์•Š์•˜์„ ๋•Œ ๊ทธ ์‹คํŒจํ•œ ๋ฉ”์†Œ๋“œ์— ๋ธŒ๋ ˆ์ดํ‚นํฌ์ธํŠธ๋ฅผ ๊ฑธ์–ด์ฃผ๊ณ 

๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ๋””๋ฒ„๊ทธ๋กœ ์‹คํ–‰์„ ํ•ด์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์ฃผ๋ฉด ์–ด๋””๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ์ž˜ ์•Œ์ˆ˜์žˆ๋‹ค. ํ  ์•„์ฃผ ๋ชจ๋ฅด๋Š” ์†Œ๋ฆฌ๋ผ ๋ง‰๋ง‰ํ•˜๋„ค

ํ…Œ์ŠคํŠธ ๋ถ€๋ถ„์—์„œ log ์ž‘์„ฑ์„ ํ•ด์ค˜๋„ใ…— ๋œ๋‹ค

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

Mock

[baeldung mock](https://www.baeldung.com/java-spring-mockito-mock-mockbean)

[MovkMvc๋ฅผ ์‚ฌ์šฉํ•ด GET, POST ํ…Œ์ŠคํŠธํ•˜๊ธฐ](https://shinsunyoung.tistory.com/52)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

Spring Security

[Spring Security ์ฒ˜๋ฆฌํ๋ฆ„์— ๋Œ€ํ•œ ์ „๋ฐ˜์ ์ธ ์„ค๋ช…](https://springsource.tistory.com/80)

Spring Security๋ฅผ ์ตœ๋Œ€ํ•œ ์‰ฝ๊ฒŒ(?) ์„ค๋ช…ํ•œ ๊ธ€ ๋ชจ์Œ [1](https://hyunsangwon93.tistory.com/24) [2](https://hyunsangwon93.tistory.com/26) [3](https://hyunsangwon93.tistory.com/27)

[Spring Security ์ธ๊ฐ€ ์ฒ˜๋ฆฌ ์„ค๋ช…](https://zgundam.tistory.com/57?category=430446)

HTTP ์„ธ์…˜

HTTP ์„ธ์…˜ ๊ฐœ์š”

Redis๋ฅผ ํ™œ์šฉํ•œ Spring Boot ์„ธ์…˜ ํด๋Ÿฌ์Šคํ„ฐ ์˜ˆ์ œ

JWT

JWT ์†Œ๊ฐœ

Java-Jwt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

Spring-Boot, Security๋กœ ๊ตฌํ˜„ํ•˜๋Š” Jwt

Jwt ์ฝ˜์†” (Jwt ๋””์ฝ”๋“œ ๋ฐ ๊ฒ€์ฆ)

Spring Validation

Java Optional

์ž๋ฐ”์—์„œ NULL์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•

Lambdas & Stream API

์ž๋ฐ”๋Š” 8๋ฒ„์ „ ์ด์ „๊ณผ ๊ทธ ์ดํ›„๋กœ ๋‚˜๋ˆ„์–ด ์ง‘๋‹ˆ๋‹ค. ๊ทธ ์ค‘์‹ฌ์—๋Š” Stream API์™€ ๋žŒ๋‹ค ํ‘œํ˜„์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ผํด ์›น์‚ฌ์ดํŠธ์˜ [Java8 Lambdas, Part1](https://www.oracle.com/technical-resources/articles/java/architect-lambdas-part1.html) ๋ฒˆ์—ญ๊ธ€์ž…๋‹ˆ๋‹ค.

Stream API์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€