code , readability ,

๊ฐ€๋…์„ฑ ์žˆ๋Š” ์ข‹์€ ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

by Mimul FollowJuly 14, 2023 ยท 10 min read ยท Last Updated:
Share this

๊ฐœ๋ฐœ ๋ฉค๋ฒ„, ํŠนํžˆ ์‹ ๊ทœ ์ฐธ๊ฐ€์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์งœ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ณ , ๋ณต์žก์„ฑ์ด ์ค„์–ด๋“ค์–ด ๋ฒ„๊ทธ๋ฅผ ์ค„์ด๋Š” ํšจ๊ณผ๋„ ์žˆ์–ด ์ƒ์‚ฐ์„ฑ์œผ๋กœ ์ง๊ฒฐ๋œ๋‹ค. ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋Š” ์žฅ๊ธฐ์ ์œผ๋กœ ๋ณด๊ณ  ์œ ์ง€ํ•˜๊ธฐ ์‰ฌ์›Œ ๊ธฐ์ˆ ์  ๋ถ€์ฑ„๋ฅผ ์ค„์—ฌ ์ค€๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ€๋…์„ฑ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์งœ๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•œ ์ผ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์•ผ ํ•œ๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์ 

1. ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋Š” ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.

์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์–‘์„ ์ค„์ด๋Š” ๊ฒŒ ์ œ์ผ ์ข‹๋‹ค. The XP 2002 Conference์—์„œ Standish Group์˜ ํšŒ์žฅ์ธ Jim Johnson์˜ ๊ธฐ์กฐ ๊ฐ•์—ฐ "ROI, It's Your Job"์—์„œ ์†Œ๊ฐœ์ฒ˜๋Ÿผ ์ œํ’ˆ์„ ์œ„ํ•œ ๋งŒ๋“ค์–ด์ง„ ๊ธฐ๋Šฅ์˜ 64%๊ฐ€ ๊ฑฐ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. Feature๋ฅผ ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ๋„ ์ฝ”๋“œ์–‘์„ ์ค„์ด๋Š” ์ผ์ด๊ณ , ์ฝ”๋“œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฏธ๋ž˜์— ํ•„์š”ํ•˜๋‹ค๊ณ  ๋ฏธ๋ฆฌ ๋งŒ๋“ค ํ•„์š”๋Š” ์—†๋‹ค. ๊ธฐ๋Šฅ, ์ฝ”๋“œ๋Š” ํ•„์š”ํ•˜๊ฒŒ ๋˜์—ˆ์„ ๋•Œ์— ๊ตฌํ˜„๋˜์–ด์•ผ ํ•˜๊ณ , ์žฅ๋ž˜ ํ•„์š”ํ•˜๊ฒŒ ๋˜๋Š” ์ด์œ ๋กœ ๊ตฌํ˜„๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

์ข‹์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ข‹์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ›Œ๋ฅญํ•œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2. ์–ด์„คํ”ˆ ์ตœ์ ํ™”๋Š” ํ•˜์ง€ ์•Š๋Š”๊ฒŒ ๋‚ซ๋‹ค.

Knuth๊ฐ€ ์ž‘์„ฑํ•œ "Computer programming as an art" ๋…ผ๋ฌธ์— ๋ณด๋ฉด "Premature optimization is the root of all evil"์ด๋ž€ ๋ง์ด ๋‚˜์˜ค๋Š”๋ฐ, ํšจ๊ณผ๊ฐ€ ์ ์€ ์ตœ์ ํ™”๋Š” ํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์žˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š” ํšจ๊ณผ๊ฐ€ ์ ์€ ์ฝ”๋“œ์˜ ์ตœ์ ํ™”๋ฅผ ํ•  ๊ฒฝ์šฐ, ์‹œ์Šคํ…œ์˜ ๋™์ž‘์€ ์ „ํ˜€ ๋ณ€ํ•˜์ง€ ์•Š์ง€๋งŒ, ๊ฐœ๋ฐœ ๋น„์šฉ์ด ๋“ค์–ด๊ฐ€๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•ด์„œ๋Š” ๊ณ ๋ฏผ์„ ํ•ด๋ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ™์€ ๋™์ž‘์— ๋˜ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•œ๋‹ค๋ฉด ๋˜ ์ฝ๋Š” ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

3. SOLID(๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™)

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

SOLID

๊ฐ€๋…์„ฑ ์žˆ๋Š” ์ฝ”๋“œ ์ž‘์„ฑ

๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์„ ๋จผ์ € ์ดํ•ดํ•œ ๋‹ค์Œ ์ฝ”๋”ฉ์„ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ฝ”๋”ฉ์‹œ ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค์„ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฉด ๊ทธ ์ฝ”๋“œ๋ฅผ ์ฝ๊ธฐ ํŽธํ•ด์•ผ ๋นจ๋ฆฌ ํŒŒ์•…ํ•ด ์ฝ”๋”ฉ ์†๋„๋ฅผ ๋Š๋ฆฌ๊ฒŒ ํ•˜์ง€ ์•Š๊ฒŒ ๋˜๊ณ , ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—์„œ ์ž์‹ ์˜ ์ฝ”๋“œ๋ฅผ ๋‚จ๋“ค์—๊ฒŒ ์„ค๋ช…ํ•˜๊ฑฐ๋‚˜ ๋‚จ๋“ค์ด ๋‚ด ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๋Š”๋ฐ ๋“œ๋Š” ๋น„์šฉ๋„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. ์ž์‹ ์˜ ์ฝ”๋“œ๋ฅผ ์“ฐ๋Š” ์‹œ๊ฐ„๊ณผ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์— ๋“œ๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. ๋ฌผ๋ก  ์ƒˆ๋กœ์šด ์‚ฌ๋žŒ์ด ์™”์„๋•Œ ๊ทธ ์‚ฌ๋žŒ์ด ๋งก์€ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๋„ ์ฝ๊ธฐ๊ฐ€ ์‰ฌ์›Œ์•ผ ๋ถ„์„ํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

1. ๋„ค์ด๋ฐ

์šฐ์„  Type(ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค ๋“ฑ), Value(๋ณ€์ˆ˜, ํ•„๋“œ, ๋งค๊ฐœ ๋ณ€์ˆ˜ ๋“ฑ) ๋ฐ ์ ˆ์ฐจ(ํ•จ์ˆ˜, ๋ฉ”์†Œ๋“œ, ์„œ๋ธŒ ๋ฃจํ‹ด ๋“ฑ)๋“ฑ์€ "What"์„ ํ‘œํ˜„ํ•˜๋Š”๊ฒŒ ์ค‘์š”ํ•˜๋‹ค. ๋ฌด์—‡์„ ๋‚˜ํƒ€๋‚ด๋Š”์ง€๋ฅผ ๋„ค์ด๋ฐ์„ ํ†ตํ•ด ์•Œ๋ ค์ค˜์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด์„œ flag๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒฝ์šฐ๋Š” is, was, should, can, may, will ๋“ฑ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ  check์˜ ์˜๋ฏธ์ธ ๊ฒฝ์šฐ is, query, verify, mesaure, filter, notify, update, valid, complated๋กœ ์‹œ์ž‘ํ•˜๋Š”๊ฒŒ ์ข‹๊ณ  ๊ณผ๊ฑฐ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๊ฒฝ์šฐ previous, stored, expired, invalidated, deprecated ๋“ฑ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹จ์–ด์˜ ์„ ํƒ์€ ๋ชจํ˜ธ์„ฑ์ด ์ ์€, ํ˜ผ๋ž€์„ ์•ผ๊ธฐํ•˜์ง€ ์•Š๋Š” ๋‹จ์–ด๋ฅผ ์„ ํƒํ•œ๋‹ค. processData, cleanData, normalizeData, sortData, mergeData ๋“ฑ์ฒ˜๋Ÿผ ๋ชจํ˜ธํ•œ ๋„ค์ด๋ฐ์„ ์“ฐ์ง€ ๋ง๊ณ  ๊ตฌ์ฒด์ ์ธ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค.

2. ์ฝ”๋ฉ˜ํŠธ

๋ณต์žกํ•œ ์ฝ”๋“œ๋‚˜ ํฐ ์ฝ”๋“œ, ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด ์ฝ”๋“œ์—๋Š” ์ฝ”๋ฉ˜ํŠธ๋ฅผ ์“ฐ๋Š” ๊ฒƒ์œผ๋กœ ๋…์ž์˜ ์ดํ•ด๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๋‹ค. ์ƒ๋‹จ ์š”์•ฝ๋ถ€๋ถ„์€ "What, Why not"์„ ๊ด€์ ์œผ๋กœ ๋ฌด์—‡์„ ํ•˜๊ณ  ์žˆ๊ณ  ๋ถ€์ž‘์šฉ์€ ๋ฌด์—‡์ธ์ง€ ๋‚ด์šฉ์— ๋“ค์–ด๊ฐ€๋ฉด ์ข‹๋‹ค. ์ธ๋ผ์ธ ์ฝ”๋ฉ˜ํŠธ๋Š” ๋  ์ˆ˜์žˆ์œผ๋ฉด ์•ˆ์“ฐ๋Š”๊ฒŒ ์ข‹์€๋ฐ ์จ์•ผํ•  ๊ฒฝ์šฐ๋Š” ์ฝ”๋“œ ๋ธ”๋ก์ด ํฌ๊ฑฐ๋‚˜ ์ง๊ด€์ ์ด์ง€ ์•Š๋Š” ์ฝ”๋“œ, ์ฃผ์˜๋ฅผ ์š”ํ•˜๋Š” ๊ฒฝ์šฐ์— ํ•œํ•ด ์ธ๋ผ์ธ ์ฝ”๋ฉ˜ํŠธ๋ฅผ ๋‹ค๋Š”๊ฒŒ ์ข‹๋‹ค.

3. ๋กœ์ง์˜ ๋ณต์žก์„ฑ ์ค„์ด๊ธฐ

3.1 Type(ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค, ๋ชจ๋“ˆ ๋“ฑ)

SOLID(๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™) ๊ด€์ ์—์„œ ์„ค๊ณ„๋ฅผ ํ•˜๊ณ  ๊ธด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒดํ™”ํ•ด์„œ ๊ณตํ†ตํ™”ํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ํŠน์„ฑ์ด ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ƒ์† ํ˜•ํƒœ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค. ์˜์กด์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์„ ํ•ด์•ผํ•œ๋‹ค. ์˜์กด์„ฑ ์ค„์ด๋Š”๋ฐ์—๋Š” ์ฃผ๋กœ ๊ฒฐํ•ฉ๋„(coupling) ๊ด€์ ์—์„œ ๋ณผ ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ํŠนํžˆ ํ”ผํ•ด์•ผ ํ•  ๊ฒฐํ•ฉ๋„๋Š” Content coupling, Common coupling, Control Coupling ์ •๋„์ด๋‹ค. External Coupling์€ Content์™€ Common coupling์ด ๋˜์ง€ ์•Š๋Š” ์ด์ƒ ์™ธ๋ถ€ ๋ชจ๋“ˆ์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ถ”์„ธ์—ฌ์„œ ์ œ์™ธํ•œ๋‹ค.

Coupling

  • Content coupling์€ ๋Œ€์ƒ์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„(์ƒํƒœ, ์ œ์–ด ํ๋ฆ„)์— ์ง์ ‘ ์˜์กดํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ „์ฒ˜๋ฆฌ, ํ›„์ฒ˜๋ฆฌ ๋“ฑ ์ˆœ์„œ ์ƒํƒœ๊ฐ€ ์žˆ์–ด์„œ ์ˆœ์„œ๋ฅผ ์ž˜๋ชป ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋นผ๋จน์œผ๋ฉด ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. Content coupling์€ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์€ํํ•˜๊ฑฐ๋‚˜, ๊ฐ’์˜ ์ „๋‹ฌ์— ์ธ์ˆ˜๋‚˜ ๋ฐ˜ํ™˜๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
public class TabakoCalculator {
    public calculatorTotal() {
        calculator.parameter = 5000;
 
        calculator.prepareProcess();
        calculator.calculate();
        calculator.postProcess();
 
        Bigdecimal totalAmount = calculator.result;
      
    }
}

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public class TabakoCalculator {
    public calculatorTotal() {
		Bigdecimal totalAmount = calculator.calculatorTotal(5000);
    }
}
  • Common coupling์€ ์ „์—ญ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ข…์†์„ฑ์ด๋‹ค. ๋Œ€ํ‘œ์ ์ธ ๊ฒŒ ๊ฐ€๋ณ€์  ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์— ํ•ด๋‹น๋œ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ƒ์„ฑ์ž ์ธ์ˆ˜๋กœ์„œ ๋Œ€์ƒ์˜ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์š”์ฆ˜์€ ๋Œ€๋ถ€๋ถ„ ๋ฉ€ํ‹ฐ ์“ฐ๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์šด๋Žก๋˜์–ด ๋ฐ”๋กœ ๋ฌธ์ œ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฏ„์— ๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉ์„ ์•ˆํ•œ๋‹ค.
public class MessageUserCase {
	public MessageRepository messasgeRepository;

	public MessageUserCase() {
	}

	public List<Message> getMessage() {
		List<Message> messages = messasgeRepository.getMessages();
		return messages;
	}
}

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public class MessageUserCase {
	private final MessageRepository messasgeRepository;

	@Autowired
	public MessageUserCase(MessageRepository messasgeRepository) {
		this.messasgeRepository = messasgeRepository;
	}

	public List<Message> getMessage() {
		List<Message> messages = messasgeRepository.getMessages();
		return messages;
	}
}
  • Control coupling์€ ์ธ์ž์— ๋”ฐ๋ผ ๋™์ž‘์„ ๋ถ„๊ธฐ์‹œํ‚ค๋Š” ์ข…์†์„ฑ์„ ๋งํ•œ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ์ ˆ์ฐจ ์ž์ฒด๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์กฐ๊ฑด ๋ถ„๊ธฐ๋ฅผ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ๋กœ์ง์„ ์กฐ๊ฑด์œผ๋กœ ๋‚˜๋ˆ„์ง€ ์•Š๊ณ  ๋Œ€์ƒ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๋ฐฉ๋ฒ•, ์ „๋žต ํŒจํ„ด์„ ํ™œ์šฉํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
public class ReportGenerator {
    public void generateReport(boolean isDetailed) {
        if (isDetailed) {
            generateDetailedReport();  // Generate a detailed report
        } else {
            generateSummaryReport();  // Generate a summary report
        }
    }

    private void generateDetailedReport() {
        System.out.println("Generating detailed report...");
        // Detailed report logic
    }

    private void generateSummaryReport() {
        System.out.println("Generating summary report...");
        // Summary report logic
    }
}

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

interface Reportable {
    public void generate();
}

// Detailed report class
class DetailedReport implements Reportable {
    @Override
    public void generate() {
        System.out.println("Generating detailed report...");
        // Detailed report logic
    }
}

// Summary report class
class SummaryReport implements Reportable {
    @Override
    public void generate() {
        System.out.println("Generating summary report...");
        // Summary report logic
    }
}

public class ReportGenerator {
    private Reportable report;

    public ReportGenerator(Reportable report) {
        this.report = report;
    }

    public void generateReport() {
        report.generate();  // The specific report type handles the logic
    }
}

3.2 Value(๋ณ€์ˆ˜, ํ•„๋“œ, ๋งค๊ฐœ ๋ณ€์ˆ˜ ๋“ฑ)

์ฃผ๋กœ ๋งค์ง ๋„˜๋ฒ„ ์‚ฌ์šฉ์„ ํ•˜์ง€ ๋ง๊ณ  ํด๋ž˜์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ธด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒดํ™”ํ•ด์„œ ๊ณตํ†ตํ™”ํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ํŠน์„ฑ์ด ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ƒ์† ํ˜•ํƒœ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค.

  • ๋งค์ง ๋„˜๋ฒ„ ์‚ฌ์šฉ์„ ํ•˜์ง€ ๋ง์ž.
public double calculateTotalFee(long price) {
    return price * 1.10;
}

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public static final double TAX_RATE = 0.10;

public double calculateTotalFee(long price) {
    return price * (1 + TAX_RATE);
}
  • ๋ณ€์ˆ˜๋ช…์— ๊ตฌ์ฒด์„ฑ์„ ๋ถ€์—ฌํ•œ๋‹ค,
a = 10;
b = 20;
c = a + b;

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

int applePrice = 10;
int bananPrice = 20;
int totalPrice = applePrice + bananPrice;

3.3 ์ ˆ์ฐจ(ํ•จ์ˆ˜, ๋ฉ”์†Œ๋“œ, ์„œ๋ธŒ ๋ฃจํ‹ด ๋“ฑ)

3.3.1 ํ•จ์ˆ˜๋Š” ๋ ์ˆ˜ ์žˆ์œผ๋ฉด ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•œ๋‹ค.

์ˆœ์ˆ˜ํ•œ ํ•จ์ˆ˜๋ž€ ์ธ์ž๊ฐ€ ๊ฐ™์œผ๋ฉด ๋งค๋ฒˆ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด ํ•จ์ˆ˜ ๋ฐ–์˜ ์„ธ๊ณ„์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ ๋งํ•œ๋‹ค.

private int fee = 10;

public int calculateTotalPrice(int tabacoPrice) {
  return fee * tabacoPrice;
}

์•„๋ž˜๋Š” ์ˆœ์ˆ˜ํ•จ์ˆ˜๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค. DB๊ฐ’, ์‹œ๊ฐ„, ๋‚œ์ˆ˜ ๋“ฑ์€ ๋‚ด๋ถ€์—์„œ ์ฒ˜๋ฆฌํ•˜๋ฉด ์ˆœ์ˆ˜ํ•จ์ˆ˜๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์ธ์ž๋กœ ๋ฒ‹์•„์„œ ์ˆœ์ˆ˜ํ•จ์ˆ˜๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค.

public int calculateTotalPrice(int tabacoPrice, int fee) {
  return fee * tabacoPrice;
}

3.3.2 if์˜ ์กฐ๊ฑด์‹์— ์ด๋ฆ„์„ ๋ถ™์ด์ž

if(aaa == bbb && aaa == 1 && bbb == 2) {

}

์œ„ ์กฐ๊ฑด์‹์€ ์‚ฌ๋žŒ์ด ์•Œ๊ธฐ ์–ด๋ ต๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์กฐ๊ฑด์— ๋Œ€ํ•œ ๋„ค์ด๋ฐ์„ ํ•ด์ฃผ๋ฉด ๊ฐ€๋…์„ฑ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค. ๋ฐ˜๋ณต๋˜๋Š” ์ˆ˜์‹์ด๋ฉด ํ•จ์ˆ˜ํ™”ํ•œ๋‹ค.

boolean available = (aaa == bbb);
if (available && company.isOwner(aaa, bbb)) {
	...	
}

3.3.3 ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๊ณ ๋ คํ•œ๋‹ค.

์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๋ ค๋ฉด ๋…ผ๋ฆฌ์ ์ด๊ณ  ์ž์—ฐ์Šค๋Ÿฌ์šด ํ๋ฆ„์œผ๋กœ ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

public String sendMailForSignUpUser(User user) {
    // 1. ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ
    if !validateignUpUser(user) {
        return "Invalid user";
    }

    // 2. ๋ฉ”์ผ ๋ฐœ์†ก ์ •๋ณด DB ์ €์žฅ
    insertSignupUserMail(user);

    // 3. ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ฐ€์ž… ํ™˜์˜ ๋ฉ”์ผ ๋ณด๋‚ด๊ธฐ
    sendWelcomeMail(user);

    return "Mail sent successfully";
}

3.3.4 ์ฝ”๋“œ์˜ ์ค‘์ฒฉ์€ ์–•๊ฒŒ ์œ ์ง€ํ•œ๋‹ค.

์–ผ๋ฆฌ ๋ฆฌํ„ด ๋ฐฉ์‹์ด ์œ ์šฉํ•˜๋‹ค.

public String getGrade(int score) {
    if (90 < score) {
        return "A";
    } else {
        if (60 < score) {
            return "B";
        } else {
            return "C";
        }
    }
}

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

public String getGrade(int score) {
    if (90 < score) {
        return "A";
    }
    if (60 < score) {
        return "B";
    }
    return "C";
}

3.3.5 ์ต๋ช… ํ•จ์ˆ˜๋‚˜ ์‹ค์ธ์ˆ˜, ๋ฆฌ์‹œ๋ฒ„, ์ฝœ ๋ฐฑ ์ฒด์ธ ๋“ฑ์„ ์ด๋ฆ„์ด ์žˆ๋Š” ๋กœ์ปฌ ๋ณ€์ˆ˜๋‚˜ ํ”„๋ผ์ด๋น— ํ•จ์ˆ˜๋กœ ์˜ฎ๊ฒจ๋†“์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ์„ ์ง€ํ–ฅํ•œ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์›ํ˜•์œผ๋กœ ์ž๋ฅด๊ณ  PNG๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ํ‘œ์‹œํ•˜๋Š” ์ฝ”๋“œ์ธ๋ฐ, ์ด ์ฝ”๋“œ๋Š” ๋‘๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ํ•œ์ค„๋กœ ์ฝ”๋“œ๋Š” ๊น”๋”ํ• ์ง€ ๋ชจ๋ฅด๋‚˜ ์ „์ฒด ๋‚ด์šฉ์„ ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ด์•ผํ•˜๊ณ  ํ•จ์ˆ˜๋ณ„๋กœ ํŠน์ • ๊ฐ’์„ ๊ฒ€์‚ฌํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ๋•Œ ์ „์ฒด๋ฅผ ํŒŒ์•…ํ•ด์•ผ ํ•œ๋‹ค.

showImage(convertImage(cropImage(loadImage(imageUri), Shape.CIRCLE), ImageFormat.PNG));

๊ฐœ์„ ๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

File originalBitmap = loadImage(imageUri);
File croppedBitmap = cropImage(originalBitmap, Shape.CIRCLE);
File croppedPng = convertImage(croppedBitmap, ImageFormat.PNG);
showImage(croppedPng);

3.4 ๋‚ด๋ถ€ ๊ตฌ์กฐ ๊ฐœ์„ 

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

3.4.1 ํšจ์œจ์ ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐœ์„ 

์ •๋ ฌ๋˜์ง€ ์•Š์€ ๋ชฉ๋ก์—์„œ ํŠน์ • ๊ฐ’์„ ์„ ํ˜• ๊ฒ€์ƒ‰ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์„๋•Œ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ผ๋ฐ˜์ ์ธ ์ฝ”๋“œ์ด๋‹ค. ๊ณ„์‚ฐ๋Ÿ‰์€ O(n)์ด๋‹ค.

def find_number(numbers, target):
    for number in numbers:
        if number == target:
            return True
    return False

numbers = [5, 3, 8, 4, 2, 7, 1, 6]
print(find_number(numbers, 4))

๋ชฉ๋ก์„ ๋ฏธ๋ฆฌ ์ •๋ ฌํ•˜๊ณ  ์ด์ง„ ๊ฒ€์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ ํšจ์œจ์„ฑ์„ ๋†’์˜€๋‹ค. ๊ณ„์‚ฐ๋Ÿ‰์€ O(n)์—์„œ O(log n)์œผ๋กœ ๊ฐœ์„ ๋˜์—ˆ๋‹ค.

def find_number(numbers, target):
    # ์ •๋ ฌ
    numbers.sort()
    
    # ์ด์ง„ ํƒ์ƒ‰
    left = 0
    right = len(numbers) - 1
    while left <= right:
        mid = (left + right) // 2
        if numbers[mid] == target:
            return True
        elif numbers[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return False

numbers = [5, 3, 8, 4, 2, 7, 1, 6]
print(find_number(numbers, 4))

3.4.2 ๋ถˆํ•„์š”ํ•œ ๊ณ„์‚ฐ ๊ฐ์†Œ

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์˜ ๊ฐ’์„ ์žฌ๊ท€์ ์œผ๋กœ ๊ณ„์‚ฐํ•˜์ง€๋งŒ ๋™์ผํ•œ ๊ณ„์‚ฐ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐ˜๋ณตํ•œ๋‹ค. ๊ณ„์‚ฐ๋Ÿ‰์€ O(2^n)์•„๋‹ค.

def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(35))

๋ฉ”๋ชจํ™”(์บ์‹œ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•˜๋ฉด ๊ณ„์‚ฐ๋Ÿ‰์„ O(n)์œผ๋กœ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

def fibonacci(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        memo[n] = n
    else:
        memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
    return memo[n]

print(fibonacci(35))

3.4.3 ์ ์ ˆํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ์‚ฌ์šฉ

๋ชฉ๋ก์—์„œ ์ค‘๋ณต์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด ์•„๋ž˜๋Š” ๊ณ„์‚ฐ๋Ÿ‰์ด O(n^2)์ด ๋œ๋‹ค.

def has_duplicate(elements):
    for i in range(len(elements)):
        for j in range(i + 1, len(elements)):
            if elements[i] == elements[j]:
                return True
    return False

elements = [1, 2, 3, 4, 5, 2]
print(has_duplicate(elements))

set๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘๋ณต์„ ํšจ์œจ์ ์œผ๋กœ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ณ„์‚ฐ๋Ÿ‰์€ O(n)์œผ๋กœ ๊ฐœ์„ ๋˜์—ˆ๋‹ค.

def has_duplicate(elements):
    return len(elements) != len(set(elements))

elements = [1, 2, 3, 4, 5, 2]
print(has_duplicate(elements))
4. ์ฝ”๋“œ์˜ ์ตœ์ ํ™”

์ƒํƒœ(state), ๊ฒฐํ•ฉ(coupling), ๋ณต์žก์„ฑ(complexity), ์ฝ”๋“œ๋Ÿ‰(code) ์ˆœ์œผ๋กœ ์ค„์ž„์œผ๋กœ์จ ์ฝ”๋“œ๋ฅผ ์ตœ์ ํ™”ํ•˜๋ฉด ์ข‹๋‹ค. ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š” ๋กœ์ง์€ ์ฝ”๋“œ ์‹คํ–‰, ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋˜๋Š” ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ด ํ™•์žฅ์„ฑ์ด ์ข‹๊ณ , ์ƒํƒœ ์žฌํ˜„ ์ฝ”๋“œ๊ฐ€ ํ•„์š”์—†์–ด ํ…Œ์ŠคํŠธ๊ฐ€ ํŽธํ•˜๊ณ  ์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์ด ์ค„์–ด๋“ ๋‹ค.

5. ์˜์กด ๋ฐฉํ–ฅ
  • ์˜์กด ๊ด€๊ณ„๋Š” ๋‹จ๋ฐฉํ–ฅ์ด์–ด์•ผ ํ•˜๊ณ  ์ˆœํ™˜ ์˜์กด์„ฑ์ด ๋ฐœ์ƒํ•˜๋ฉด ์•ˆ๋œ๋‹ค
  • ๋ฐ”๋žŒ์งํ•œ ์˜์กด ๊ด€๊ณ„๋Š” ํ˜ธ์ถœํ•˜๋Š” ์ธก์ด ํ˜ธ์ถœ๋˜๋Š” ์ธก์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค
  • ๊ตฌํ˜„(์ƒ์„ธ) ํด๋ž˜์Šค๋Š” ์ถ”์ƒ ํด๋ž˜์Šค์— ์˜์กดํ•œ๋‹ค
  • ๋ณต์žกํ•œ ๊ฒƒ์ด ๋‹จ์ˆœํ•œ ๊ฒƒ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค

ํˆด๊ณผ ๊ฐ€์ด๋“œ ํ™œ์šฉ

1. Code Style Guide
2. Code Formatter

์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ์„ ์œ„ํ•œ ์ถ”์ฒœ ๋„์„œ