Refactoring - cleancodeclass/cleancode_theory GitHub Wiki

Refactoring ์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

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

์™œ Refactoring์„ ํ•˜๋Š”๊ฐ€?

  • ์†Œํ”„ํŠธ์›จ์–ด ์„ค๊ณ„๊ฐ€ ๊ฐœ์„ ๋˜๋‹ˆ๊นŒ : ์ค‘๋ณต๋œ ์ฝ”๋“œ๊ฐ€ ์—†์–ด์ง€๋ฉด์„œ ์„ค๊ณ„๊ฐ€ ๊ฐœ์„ ๋œ๋‹ค.
  • ์†Œํ”„ํŠธ์›จ์–ด ์ดํ•ด๊ฐ€ ๋” ์‰ฌ์›Œ์ง€๋‹ˆ๊นŒ : ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ ธ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฒ„๊ทธ๋ฅผ ์ฐพ๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์ง€๋‹ˆ๊นŒ : ํ”„๋กœ๊ทธ๋žจ ๊ตฌ์กฐ์˜ ๋‹จ์ˆœโˆ™๋ช…๋ฃŒํ™”๋กœ ๋ฒ„๊ทธ ์›์ธ์„ ์‰ฝ๊ฒŒ ์ฐพ๋Š”๋‹ค.
  • ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€๋‹ˆ๊นŒ : ๊น”๋”ํ•œ ์„ค๊ณ„๋กœ ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์†๋„๊ฐ€ ๋†’์•„์ง„๋‹ค.

์–ธ์ œ ๋ฆฌํŒฉํ† ๋ง์„ ํ•˜๋Š”๊ฐ€?

  • ์ž‘์ •ํ•˜๊ณ  ๋”ฐ๋กœ ์‹œ๊ฐ„์„ ๋‚ด์„œ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ผ์ƒ์ ์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    • ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๋•Œ
    • ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ
    • ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ํ•  ๋•Œ
  • ๊ฐœ๋ฐœ ์ค‘์— ๋Šฅ๋ฅ ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด์„œ ํ‹ˆํ‹ˆํžˆ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
    • ์ฝ”๋“œ๋ฅผ ์•Œ์•„๋ณด๊ธฐ ํž˜๋“ค ๋•Œ
    • ์ค‘๋ณต๋œ ๋กœ์ง์ด ๋“ค์–ด์žˆ์„ ๋•Œ
    • ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๋„ฃ์–ด์•ผ ํ•ด์„œ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๋•Œ
    • ์กฐ๊ฑด๋ฌธ ๊ตฌ์กฐ๊ฐ€ ๋ณต์žกํ•  ๋•Œ

๋ฆฌํŒฉํ† ๋ง ๋ฐฉ๋ฒ•

  • Find some code that โ€œsmellsโ€
  • Determine how to simplify this code
  • Make the simplifications
  • Run tests to ensure things still work correctly
  • Repeat the simplify/test cycle until the smell is gone

์ฝ”๋“œ ์Šค๋ฉœ(Code Smell)

  • ์ฝ”๋“œ์—์„œ ๋” ์‹ฌ์˜คํ•œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ ์†Œ์Šค ์ฝ”๋“œ์˜ ์ฆ์ƒ
    • ์ฝ”๋“œ ์Šค๋ฉœ์ธ์ง€ ์•„๋‹Œ์ง€์˜ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์ผ์€ ์ฃผ๊ด€์ ์ธ ๊ฒƒ
    • ์–ธ์–ด์™€ ๊ฐœ๋ฐœ์ž, ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•จ
    • ์ฝ”๋“œ ์Šค๋ฉœ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋“ค์ด ์žˆ์Œ (PMD, FindBugs ๋“ฑ)

1 duplicatedcode

  • ๋ฉ”์„œ๋“œ ์ถ”์ถœ
    • ์ฝ”๋“œ๋ฅผ ๋ฉ”์„œ๋“œ๋กœ ๋นผ๋‚ธ๋‹ค.
    • ๋ฉ”์„œ๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๊ฑฐ๋‚˜ ์ฝ”๋“œ์— ์ฃผ์„์„ ๋‹ฌ์•„์•ผ๋งŒ ์˜๋„๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๋•Œ
    • ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์€ ์ฝ”๋“œ์˜ ๋ชฉ์ ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ง๊ด€์ ์ธ ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ์—ฌ์•ผ ํ•œ๋‹ค. extractmethod

2 longmethod

  • ์กฐ๊ฑด๋ฌธ ์ชผ๊ฐœ๊ธฐ
    • if, then, else ๋ถ€๋ถ„์„ ๊ฐ๊ฐ ๋ฉ”์„œ๋“œ๋กœ ๋นผ๋‚ธ๋‹ค. DecomposeConditional

3 longparameterlist

  • ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ธํŠธ๋ฅผ ๋ฉ”์„œ๋“œ๋กœ ์ „ํ™˜
    • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์—†์• ๊ณ  ์ง์ ‘ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.
    • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ „๋‹ฌ๋ฐ›๋Š” ์ชฝ์—์„œ๋„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์„ ๋•Œ
    • ํ˜ธ์ถœํ•œ ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๊ณ„์‚ฐ์— ์‚ฌ์šฉ๋  ๋• ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค. replaceparameterwithmethod1 replaceparameterwithmethod2
  • ๊ฐ์ฒด๋ฅผ ํ†ต์งธ๋กœ ์ „๋‹ฌ
    • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ์ฒด๋กœ ์ „๋‹ฌํ•ด ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ค„์ธ๋‹ค.
    • ๊ฐ์ฒด์—์„œ ๊ฐ€์ ธ์˜จ ์—ฌ๋Ÿฌ ๊ฐ’์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•  ๋•Œ ๊ฐ์ฒด๋ฅผ ํ†ต์งธ๋กœ ์ „๋‹ฌํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.
    • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋งŽ์•„์ง€๋ฉด ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๋ฏ€๋กœ ๊ฐ€๋Šฅํ•œ ์ค„์—ฌ์•ผ ํ•œ๋‹ค. ๋‹จ, ์ „๋‹ฌ๋˜๋Š” ๊ฐ์ฒด์™€ ์˜์กด์„ฑ์ด ๊ฐ•ํ™”๋˜๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. parameter
  • ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ธํŠธ๋ฅผ ๊ฐ์ฒด๋กœ ์ „ํ™˜
    • ๋Š˜ ํ•จ๊ป˜ ์ „๋‹ฌ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ญ‰์น˜๋ฅผ ๊ฐ์ฒด๋กœ ์ „๋‹ฌํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค.
    • ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ธํŠธ๊ฐ€ ์งง๊ฒŒ ์ค„์–ด์„œ ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค.
    • ๋ฐ˜๋ณต๋˜๋Š” ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋กœ ์˜ฎ๊ฒจ ์ฝ”๋“œ ์ค‘๋ณต์„ ์—†์•จ ์ˆ˜ ์žˆ๋‹ค. introduce1 introduce2

4 divergentchange

  • ํด๋ž˜์Šค ์ถ”์ถœ
    • ํด๋ž˜์Šค์˜ ์ผ๋ถ€๋ฅผ ๋–ผ๋‚ด์–ด ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋กœ ๋งŒ๋“ ๋‹ค.
    • ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ํด๋ž˜์Šค๋Š” ๊ธฐ๋Šฅ ์ถ”๊ฐ€๋กœ ์ ์ฐจ ๋ฐฉ๋Œ€ํ•ด์ง„๋‹ค.
    • ์—ฌ๋Ÿฌ ํด๋ž˜์Šค๊ฐ€ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์ด ํ•˜๋‚˜์˜ ํด๋ž˜์Šค์— ๋“ค์–ด์žˆ์„ ๋•Œ extractclass1 extractclass2

5 shotgunsurgery

  • ๋ฉ”์„œ๋“œ ์ด๋™(Move Method)
    • ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ ์ด๋™ํ•˜๋Š” ๊ธฐ๋ฒ•
    • ๋ฉ”์„œ๋“œ๊ฐ€ ์ž์‹ ์˜ ํด๋ž˜์Šค๋ณด๋‹ค ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ์„ ๋” ๋งŽ์ด ์ด์šฉํ•  ๋•Œ
    • ํด๋ž˜์Šค์— ๊ธฐ๋Šฅ์ด ๋„ˆ๋ฌด ๋งŽ๊ฑฐ๋‚˜ ํด๋ž˜์Šค๊ฐ€ ์˜์กด์„ฑ์ด ์ง€๋‚˜์น  ๋•Œ movemethod
  • ํ•„๋“œ ์ด๋™(Move Field)
    • ํด๋ž˜์Šค ๋‚ด์˜ ํ•„๋“œ๋ฅผ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ ์˜ฎ๊ธด๋‹ค.
    • ์ž์‹ ์ด ์†ํ•œ ํด๋ž˜์Šค๋ณด๋‹ค ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ๋” ๋งŽ์ด ์‚ฌ์šฉ๋  ๋•Œ movefield1 movefield2
  • ํด๋ž˜์Šค ๋‚ด์šฉ ์ง์ ‘ ์‚ฝ์ž…(Inline Class)
    • ํด๋ž˜์Šค์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ ํ•ฉ์ณ ๋„ฃ๋Š”๋‹ค.
    • ํด๋ž˜์Šค ์ถ”์ถœ (Extract Class)๊ณผ ๋ฐ˜๋Œ€๋˜๋Š” ๊ฐœ๋…
    • ํด๋ž˜์Šค์˜ ๊ธฐ๋Šฅ ๋Œ€๋ถ€๋ถ„์„ ์ด๋™์‹œ์ผœ ๋‚จ์€ ๊ธฐ๋Šฅ์ด ๊ฑฐ์˜ ์—†์„ ๋•Œ
    • ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ ๊ณจ๋ผ์„œ ํ•ฉ์นœ๋‹ค.

6 featureenvy

7 switchstatement

  • Replace Type Code with State / Strategy
    • ๋ถ„๋ฅ˜ ๋ถ€ํ˜ธ๋ฅผ ์ƒํƒœ/ ์ „๋žต ํŒจํ„ด์œผ๋กœ ์ „ํ™˜
    • ์ƒํƒœ / ์ „๋žต ํŒจํ„ด์„ ์ด์šฉํ•ด์„œ ๋ถ„๋ฅ˜ ๊ธฐํ˜ธ๋ฅผ ์—†์• ๋Š” ๊ธฐ๋ฒ•
    • ๋ถ„๋ฅ˜ ๋ถ€ํ˜ธ๋ฅผ ํ•˜์œ„ํด๋ž˜์Šค๋กœ ์ „ํ™˜ (with Subclasses)๊ณผ ๋น„์Šทํ•œ ๊ธฐ๋ฒ•
    • ๋ถ„๋ฅ˜ ๋ถ€ํ˜ธ๊ฐ€ ๊ฐ์ฒด ์ˆ˜๋ช…์ฃผ๊ธฐ ๋™์•ˆ ๋ณ€ํ•  ๋•Œ๋‚˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ r1 r2

8 comment

๊ฐ„๋‹จํ•œ Cleancode Refactoring ์‚ฌ๋ก€?

cleancode1 cleancode2 cleancode3 cleancode4 cleancode5-1 cleancode5-2 cleancode5-3