E D R , A S I H C RSS

Refactoring Discussion

Refactoring κ³Ό κ΄€λ ¨λœ ν† λ‘ , 질문/λ‹΅λ³€μ˜ μž₯으둜 ν™œμš©ν•œλ‹€.

ν˜„μž¬ κ²Œμ‹œνŒμ— μžˆλŠ” 글을 κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.(쑰금 손봄) μ˜λ„μ— λ§žμ§€ μ•ŠλŠ” 뢀뢄은 μˆ˜μ • λ°”λžλ‹ˆλ‹€.


refactoring 의 μ „μ œ 쑰건은, Refactoring μ „ ν›„μ˜ κ²°κ³Όκ°€ κ°™μ•„μ•Ό ν•œλ‹€. λΌλŠ” 것이닀.

Martin Folwer의 Refactoring p326(ν•œμ„œ), 10μž₯의 Parameterize Method λΌ μ‚΄νŽ΄λ³΄λ©΄ λ‹€μŒκ³Ό 같은 λ‚΄μš©μ΄ λ‚˜μ˜¨λ‹€.


~cpp 
protected Dollars baseCharge() {
  double result = Math.min(lastUsage(),100) * 0.03;
  if (lastUsage() > 100) {
    result += (Math.min (lastUsage(),200) - 100) * 0.05;
  };
  if (lastUsage() > 200) {
    result += (lastUsage() - 200) * 0.07;
  };
  return new Dollars (result);
}


이것은 λ‹€μŒκ³Ό 같이 λŒ€μ²΄λ  수 μžˆλ‹€.

protected Dollars baseCharge() {
  double result = usageInRange(0, 100) * 0.03;      //--(1)
  result += usageInRange (100,200) - 100) * 0.05;
  result += usageInRange (200, Integer.MAX_VALUE) * 0.07;
  return new Dollars (result);
}

protected int usageInRange(int start, int end) {
  if (lastUsage() > start) return Math.min(lastUsage(),end) - start;
  else return 0;
}


(1) 의 μ½”λ“œλΌ μ‚΄νŽ΄λ³΄λ©΄ 둜직이 달라짐을 μ•Œ 수 μžˆλ‹€. 처음의 μ½”λ“œλŠ” 더 μž‘μ€ 값을 원할 뿐인데, μ•„λž˜μ˜ μ½”λ“œμ—μ„œλŠ” 0 보닀 μž‘μ€ 값은 κ°€μ§ˆ 수 μ—†κ²Œ λ˜μ–΄μžˆλ‹€. (μ˜ˆλΌ λ“€μ–΄ lastUsage() μŒμˆ˜κ°’μ„ μ§€λ‹ˆλ©΄ κ²°κ³Όκ°€ 달라진닀)

"MatrinFowler의 μΆ”μ’…μžλ“€μ€ lastUsage()κ°€ 0 이상인 값에 λŒ€ν•΄ λ™μž‘ν•˜λŠ”κ²ƒμΌν…Œλ‹ˆ (μ½”λ“œλΌ λ³΄κ³  μΆ”μ •ν•˜λ©΄ κ·Έλ ‡λ‹€) λ‹Ήμ—°ν•œκ±° μ•„λ‹ˆλƒ?" 라고 μ΄μ˜λΌ μ œκΈ°ν• μ§€λŠ” λͺ¨λ₯΄μ§€λ§Œ, 이건 Refactoring μ—μ„œ ν•œκ²°κ°™μ΄ μΆ”κ΅¬ν–ˆλ˜ "μ˜λ„λΌ λͺ…ν™•ν•˜κ²Œ"λΌλŠ” 뢀뢄을 Refactoringμ΄λΌλŠ” 도ꡬ에 λΌμ›Œλ§žμΆ”λ‹€λ³΄λ‹ˆ μ˜λ„λΌ λΆˆλͺ…ν™•ν•˜κ²Œ ν•œ κ²°κ³ΌλΌ λ‚³μ€κ²ƒ κ°™λ‹€. (망치의였λ₯˜)

μœ„μ˜ (1)번 μ½”λ“œλŠ” μ›λž˜μ²˜λŸΌ κ·ΈλŒ€λ‘œ λ‘κ±°λ‚˜, usageInRange(Integer.MIN_VALUE, 100)으둜 ν˜ΈμΆœν•˜λŠ”κ²Œ λ§žμ„ λ“ ν•˜λ‹€.

ν•˜μ§€λ§Œ 이것도 μž„μ‹œ 방편일뿐, μœ„ν—˜μ€ μ‘΄μž¬ν•œλ‹€. lastUsage()의 값이 Integer.MIN_VALUE μ΄κ±°λ‚˜, Integer.MAX_VALUE 라면? (이런일이 κ²°μ½” 일어날 수 μ—†λ‹€κ³  μž₯λ‹΄ν•  수 μžˆλŠ”κ°€?)

-- μ΄μ„ μš°


  • μ½”λ“œμ˜ μ˜λ„κ°€ ν‹€λ ΈλŠλƒμ— λŒ€ν•œ 검증 - 만일 ν”„λ‘œκ·Έλž¨ λ‚΄μ—μ„œμ˜ μ˜λ„ν•œλ°”κ°€ λ§žλŠ”μ§€μ— λŒ€ν•œ 검증은 UnitTest Code μͺ½μœΌλ‘œ λ„˜κΈ°λŠ”κ²Œ λ‚˜μ„ 것 κ°™λ‹€κ³  생각이 λ“œλ„μš”. κΈ€μ˜ λ‚΄μš©λ„ 결ꡭ은 전체 Context λ‚΄μ—μ„œ νŒŒμ•…ν•΄μ•Ό ν•˜λ‹ˆκΉŒ. μ˜λ„κ°€ μ€‘μ‹œλœλ‹€λ©΄ Test Code λŠ” ν•„μˆ˜κ² μ£ . (μ—¬κΈ°μ„œμ˜ 'μ˜λ„'λŠ” 각 λͺ¨λ“ˆλ³„ input 에 λŒ€ν•œ output μ •λ„λ‘œ λ°”κΏ”μ„œ μƒκ°ν•˜μ…”λ„ 쒋을λ“)

둜직이 λ‹¬λΌμ‘Œμ„ κ²½μš°μ— λŒ€ν•œ 검증에 λŒ€ν•΄μ„œλŠ”, Refactoring 전에 Test Code λΌ λ§Œλ“€κ²ƒμ΄κ³ , λ‘œμ§μ— λ”°λ₯Έ 수용 μ—¬λΆ€λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œμͺ½μ—μ„œ 결둠이 지어져야 될 κ²ƒμ΄λΌλŠ” 생각이 λ“­λ‹ˆλ‹€. (μ•„λ§ˆ μ˜λ„μ— λ²—μ–΄λ‚œ μ½”λ“œλ‘œ λ°”λ€Œμ–΄μ Έλ²„λ Έλ‹€λ©΄ Test Code μ—μ„œ κ²€μ¦λ˜κ² μ£ .) μ½”λ“œ 자체만 보고 λ°”λ‘œ 잘λͺ»λœ μ½”λ“œλΌκ³  단정짓기 보단 전체 ν”„λ‘œκ·Έλž¨ λ‚΄μ—μ„œ μ˜λ„μ— λ”°λ₯΄λŠ” μ½”λ“œμΌμ§€λΌ μƒκ°ν•΄μ•Ό 될 것 κ°™λ‹€λŠ” 생각.

  • 예제 μ½”λ“œλ‘œ μ μ ˆν–ˆλŠλƒ - μ€ λ” μ‰½κ²Œ μ˜λ„μ— 맞게 Refactoring λ˜μ–΄μ§„ 것이 이 예제 λ°”λ‘œ 전인 Raise 이긴 ν•˜μ§€λ§Œ. 그리 쒋은 μ˜ˆλŠ” μ•„λ‹Œλ“ ν•˜λ‹€. usageInRange 둜 λΉΌλ‚΄κΈ° μœ„ν•΄ μ•½κ°„ μΌλΆ€λŸ¬ μΌλ°˜ν™” 곡식을 λ§Œλ“€μ—ˆλ‹€κ³  ν•΄μ•Ό ν• κΉŒμš”. κ·Έ 덕에 μ½”λ“œ 자체만으둜 λœ»μ„ μ΄ν•΄ν•˜κΈ°κ°€ μ€ λͺ¨ν˜Έν•΄μ‘Œλ‹€λŠ” λΆ€λΆ„μ—λŠ” 동감.

  • Refactoring의 Motivation - Pattern 이건 Refactoring 이건 'Motivation' 뢀뢄이 있죠. 즉, 무엇을 μ˜λ„ν•˜μ—¬ μ΄λŸ¬μ΄λŸ¬ν•˜κ²Œ μ½”λ“œλΌ μž‘μ„±ν–ˆλŠ”κ°€μž…λ‹ˆλ‹€. Parameterize Method 의 μ˜λ„λŠ” 'couple of methods that do similar things but vary depending on a few values'에 λŒ€ν•œ 처리이죠. 즉, λΉ„μŠ·ν•œ 일을 ν•˜λŠ” λ©”μ†Œλ“œλ“€μ΄κΈ΄ ν•œλ° 일뢀 값듀에 영ν–₯λ°›λŠ” μ½”λ“œλ“€μ— λŒ€ν•΄μ„œλŠ”, κ·Έ 영ν–₯λ°›κ²Œ ν•˜λŠ” 값듀을 parameter 둜 λ„£μ–΄μ£Όκ²Œλ” ν•˜κ³ , 같은 일을 ν•˜λŠ” 뢀뢄에 λŒ€ν•΄μ„  λ¬ΆμŒμœΌλ‘œμ„œ 쀑볡을 μ„이고, μΆ”ν›„ 쀑볡이 될 뢀뢄듀이 적어지도둝 ν•˜μžλŠ” 것이겠죠. -- μ„μ²œ


μ•ž 글은 μ§ˆλ¬Έμ΄λΌκΈ°λ³΄λ‹€λŠ” 지적과 λΉ„νŒμΈ λ“ ν•©λ‹ˆλ‹€.

κ·Έ 지적을 μΆ©λΆ„νžˆ μ΄ν•΄ν•©λ‹ˆλ‹€.

λ¦¬νŒ©ν† λ§μ€ μ½”λ“œμ˜ 외뢀적 행동을 바꾸지 μ•ŠμœΌλ©΄μ„œ 내뢀적 κ΅¬μ‘°λΌ λ³€ν™˜ν•˜λŠ” 것을 λ§ν•©λ‹ˆλ‹€. μ—¬κΈ°μ„œ 핡심은 "외뢀적 행동"에 μžˆμŠ΅λ‹ˆλ‹€. μ €λŠ” 이 "외뢀적 행동"을 "의λΈμžˆλŠ”/μ˜λ„ν•˜λŠ” 외뢀적 행동"으둜 λ΄…λ‹ˆλ‹€ -- μ–΄μ°¨ν”Ό μš°λ¦¬μ—κ² μ½”λ“œ μžμ²΄κ°€ ꢁ극이 μ•„λ‹ˆκ³  κ·Έ μ½”λ“œκ°€ ν˜„μ‹€μ— λ“œλŸ¬λ‚΄λŠ” "μ‹œμŠ€ν…œ"이 ꢁ극이기 λ•Œλ¬Έμ—.

κ·Έλ ‡λ‹€λ©΄, λͺ¨λ“  μƒνƒœ 곡간이 μœ μ§€λ˜μ–΄μ•Ό ν•˜λŠ” 것은 μ•„λ‹™λ‹ˆλ‹€. μ–΄μ°¨ν”Ό μ›λž˜ μ½”λ“œ μžμ²΄κ°€ μΈκ°„μ˜ μ•„μ΄λ””μ–΄λΌ "μ–΄μ„€ν”„κ²Œ" ν‘œν˜„ν•΄ λ‚Έ 것이고, κ±°κΈ°μ„œλΆ€ν„° μ΄λΈ μƒνƒœ 곡간은 μ’ν˜€μ§€κ±°λ‚˜, λŠ˜λ €μ ΈμžˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 이런 λ…Όμ˜λΌ λ– λ‚˜μ„œ λ„λŒ€μ²΄ μ™œ λ¦¬νŒ©ν† λ§μ„ ν•˜λŠ”κ°€ 생각해볼 ν•„μš”κ°€ μžˆκ² μŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” λ¦¬νŒ©ν† λ§μ„ "λ¦¬νŒ©ν† λ§μ΄λΌλŠ” 것이 μ˜³λ‹€ κ·Έλ₯΄λ‹€"λΌ λ”°μ§€κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” 것이 μ•„λ‹ˆκ³ , 우리의 ν”„λ‘œκ·Έλž˜λ°μ— 도움이 되기 μœ„ν•΄ μ‚¬μš©ν•©λ‹ˆλ‹€.

λ¦¬νŒ©ν† λ§μ΄λΌλŠ” 책을 읽을 λ•Œμ—λŠ” λ…Όλ¦¬μ μœΌλ‘œ μ˜³κ±°λ‚˜ ν‹€λ¦° 뢀뢄을 μ°Ύμ•„λ‚΄λ €κ³  λ…Έλ ₯ν•˜λŠ” 것보닀, λ‚˜μ—κ²Œ 도움이 되면 μ·¨ν•˜κ³  그렇지 μ•Šλ‹€λ©΄ λ‚˜μ€‘μ„ κΈ°μ•½ν•˜λŠ” 것이 "ν”„λ‘œκ·Έλž˜λ¨Έ"μ—κ²Œ 득이 λ˜λŠ” λ“ ν•©λ‹ˆλ‹€.

λ¬Όλ‘ , 이둠을 κ³΅λΆ€ν•˜λŠ” μ „μ‚°ν•™μžμ—κ²ŒλŠ” μ€ λ‹€λ₯΄κ² μ§€μš”. ν•˜μ§€λ§Œ, λˆ„κ΅°κ°€ λ§ν•˜λ“이 "μ™„λ²½ν•œ 이둠"은 ν˜„μ‹€μ—μ„œλŠ” 큰 κ°€μΉ˜κ°€ μ—†κΈ° λ§ˆλ ¨μž…λ‹ˆλ‹€. μ €λŠ” λ¦¬νŒ©ν† λ§μ—μ„œ "μ™„λ²½ν•œ 이둠"보닀 "μœ μš©ν•œ 이둠"을 μ°ΎμŠ΅λ‹ˆλ‹€.

ps. ν˜„μ‹€μ—μ„œ 정말 λͺ¨λ“  μƒνƒœ 곡간/기계가 κ³ λŒ€λ‘œ μœ μ§€λ˜λŠ” λ¦¬νŒ©ν† λ§μ€ μ—†μŠ΅λ‹ˆλ‹€. κ°€μž₯ λŒ€ν‘œμ μΈ Extract a Method 쑰차도 λͺ¨λ“  κ²½μš°μ— λ™μΌν•œ 행동 μœ μ§€λΌ λ³΄μž₯ν•  μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€. 1+2κ°€ 2+1κ³Ό 같지 μ•Šλ‹€κ³  말할 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μš°λ¦¬μ—κ²Œ 의λΈμžˆλŠ” 정도 λ‚΄μ—μ„œ μΆ©λΆ„νžˆ μ„œλ‘œ κ°™λ‹€κ³  말할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€ -- λ¬Όλ‘  ν•„μš”μ— 따라 μ–‘μžλΌ κ΅¬λΆ„ν•  μˆ˜λ„ μžˆμ–΄μ•Όκ² μ§€λ§Œ, μ‚°μˆ˜ λ‹΅μ•ˆ μ±„μ μ‹œμ— 1+2, 2+1 쀑 μ–΄λŠ 것에 μ μˆ˜λΌ μ„ μ§€ κ³ λΌν•  ν•„μš”λŠ” μ—†κ² μ£ .

~cpp 
> { Refactoring(by Martin Fowler)의 잘λͺ»λœ refactoring }
> { μ„ μš°(guest),  }

[snip]

> 
> 
> μœ„μ˜ (1)번 μ½”λ“œλŠ” μ›λž˜μ²˜λŸΌ κ·ΈλŒ€λ‘œ λ‘κ±°λ‚˜, usageInRange(Integer.MIN_VALUE, 100)으둜
> ν˜ΈμΆœν•˜λŠ”κ²Œ λ§žμ„ λ“ ν•˜λ‹€.
> 
> ν•˜μ§€λ§Œ 이것도 μž„μ‹œ 방편일뿐, μœ„ν—˜μ€ μ‘΄μž¬ν•œλ‹€.
> 
> lastUsage()의 값이 Integer.MIN_VALUE μ΄κ±°λ‚˜, Integer.MAX_VALUE 라면?
> (이런일이 κ²°μ½” 일어날 수 μ—†λ‹€κ³  μž₯λ‹΄ν•  수 μžˆλŠ”κ°€?)
> 

μš°λ¦¬μ—κ² ν”„λ‘œκ·Έλž¨μ˜ 옳음(correctness)이 μΌμ°¨μ μž…λ‹ˆλ‹€. 이것은 UnitTestλ‚˜ Eiffel 같은 DBC μ–Έμ–΄λ‘œ μƒλ‹Ήν•œ μ •λ„κΉŒμ§€ 보μž₯ κ°€λŠ₯ ν•©λ‹ˆλ‹€.

κ·Έ λ‹€μŒμ— λΉ„λ‘œμ†Œ λ¦¬νŒ©ν† λ§μ˜ μ˜³μŒμ„ λ”°μ§ˆ μ—¬μœ κ°€ μžˆμŠ΅λ‹ˆλ‹€. ν‹€λ¦°/틀릴 수 μžˆλŠ” ν”„λ‘œκ·Έλž¨μ„ "옳게 λ¦¬νŒ©ν† λ§"ν•˜λ©΄ μ—­μ‹œ ν‹€λ¦°/틀릴 수 μžˆλŠ” ν”„λ‘œκ·Έλž¨μ΄ λ‚˜μ˜΅λ‹ˆλ‹€.

-- κΉ€μ°½μ€
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:27:52
Processing time 0.0242 sec