C refactorings and code smells catalog - minsuk-jang/teamproject GitHub Wiki

Neovim은 큰 refactoring λ…Έλ ₯μž…λ‹ˆλ‹€. 이 μ£Όμ œμ— κ΄€ν•œ λ¬Έν—Œμ—μ„œ 아이디어λ₯Ό μ–»λŠ” 것이 도움이 될 κ²ƒμž…λ‹ˆλ‹€. κΈ°μ—¬μžλŠ” μ•…μ˜μ μΈ μ½”λ“œ λƒ„μƒˆλ₯Ό κ°μ§€ν•˜κ³  였래된 / λ¬Έμ„œν™”λ˜μ§€ μ•Šμ€ / ν…ŒμŠ€νŠΈλ˜μ§€ μ•Šμ€ μ½”λ“œλ₯Ό λ‹€λ£° λ•Œ ν•„μš”ν•œ μ£Όμ˜μ‚¬ν•­μ„ μ μš©ν•˜μ—¬ ν•„μš”ν•œ refactoring을 μ μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

여기에 μžˆλŠ” λͺ©λ‘μ€ μ™„μ „ν•œ 것이 μ•„λ‹ˆλ―€λ‘œ μ½”λ“œμ—μ„œ 발견 될 μˆ˜μžˆλŠ” λ¬Έμ œμ— λŒ€ν•œ μ™„λ²½ν•œ 처방으둜 κ°„μ£Ό λ˜μ–΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. μœ΅ν†΅μ„±μžˆκ²Œ ν•˜μ‹­μ‹œμ˜€.

C Refactorings λͺ©λ‘

neovim의 μ½”λ“œλ² μ΄μŠ€λ₯Ό ν–₯μƒμ‹œν‚€λŠ” λ™μ•ˆ 우리λ₯Ό μ•ˆλ‚΄ ν•  수 μžˆλŠ” C Refactorings λͺ©λ‘.

Garrido 2000 [** ** 2.1 C refactorings λͺ©λ‘ μ œμ•ˆ ** ** (page 17)

ν”„λ‘œκ·Έλž¨ entity μΆ”κ°€ν•˜κΈ°

  • λ³€μˆ˜ μΆ”κ°€
  • ν•¨μˆ˜μ— 맀개 λ³€μˆ˜ μΆ”κ°€
  • κΈ°μ‘΄ μœ ν˜•μ„ μΊ‘μŠν™”ν•˜λŠ” typedef μ •μ˜ μΆ”κ°€
  • ꡬ쑰체에 ν•„λ“œ μΆ”κ°€
  • **λ³€μˆ˜μ— 포인터λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€ : **μ„ νƒλœ λ³€μˆ˜μ˜ μœ ν˜•κ³Ό λ™μΌν•œ μœ ν˜•μ˜ 포인터 λ³€μˆ˜μ˜ 선언을 μΆ”κ°€ν•˜κ³  포인터에 μ„ νƒν•œ λ³€μˆ˜μ˜ μ£Όμ†Œλ₯Ό ν• λ‹Ήν•˜μ‹­μ‹œμ˜€.

ν”„λ‘œκ·Έλž¨ entity μ‚­μ œ

  • μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” λ³€μˆ˜ μ‚­μ œ
  • μ‚¬μš©ν•˜μ§€ μ•Šμ€ 맀개 λ³€μˆ˜ μ‚­μ œ
  • ν•¨μˆ˜ μ‚­μ œ

ν”„λ‘œκ·Έλž¨ entity λ³€κ²½

  • λ³€μˆ˜ 이름 λ³€κ²½
  • μƒμˆ˜ 이름 λ³€κ²½
  • μ‚¬μš©μž μ •μ˜ μœ ν˜• 이름 λ³€κ²½
  • ꡬ쑰 ν•„λ“œ 이름 λ³€κ²½
  • ν•¨μˆ˜ λ³€κ²½
  • ν”„λ‘œκ·Έλž¨ entity의 μœ ν˜• λ³€κ²½
  • 계약 λ³€μˆ˜ λ²”μœ„
  • κ°€λ³€ λ²”μœ„ ν™•μž₯
  • 값을 μƒμˆ˜λ‘œ λ³€κ²½
  • ν‘œν˜„μ‹μ„ λ³€μˆ˜λ‘œ λ³€κ²½
  • λ³€μˆ˜λ₯Ό ν¬μΈν„°λ‘œ λ³€ν™˜
  • 포인터λ₯Ό 직접 λ³€μˆ˜ μ ‘κ·ΌμœΌλ‘œ λ³€ν™˜
  • μ „μ—­ λ³€μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ³€ν™˜ : μ§€μ •λœ μ „μ—­ λ³€μˆ˜μ— μ ‘κ·Όν•˜λŠ” λͺ¨λ“  ν•¨μˆ˜λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€. 각 ν•¨μˆ˜μ— λŒ€ν•΄ ν˜•μ‹ μ •μ˜ 맀개 λ³€μˆ˜λ₯Ό ν•¨μˆ˜ μ •μ˜μ— μΆ”κ°€ν•˜κ³ , μ „μ—­ λ³€μˆ˜λ₯Ό ν•¨μˆ˜ ν˜ΈμΆœμ—μ„œ μ‹€μ œ 맀개 λ³€μˆ˜λ‘œ μΆ”κ°€ ν•œ λ‹€μŒ 맀개 λ³€μˆ˜μ— λŒ€ν•œ ν•¨μˆ˜ λ‚΄μ˜ μ „μ—­ λ³€μˆ˜μ— λŒ€ν•œ 접근을 λ°”κΎΈμ‹­μ‹œμ˜€. μ‚¬μš©μžλŠ” 맀개 λ³€μˆ˜κ°€ 포인터 μœ ν˜•μΈμ§€ 선택할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • **ν•¨μˆ˜ 인수 μž¬μ •λ ¬ : ** ν•¨μˆ˜ μ •μ˜ 및 ν•΄λ‹Ή ν•¨μˆ˜μ— λŒ€ν•œ λͺ¨λ“  ν˜ΈμΆœμ—μ„œ 인수의 μˆœμ„œλ₯Ό λ³€κ²½ν•©λ‹ˆλ‹€.

λ³΅μž‘ν•œ refactorings

  • μƒˆλ‘œμš΄ κ΅¬μ‘°μ—μ„œ 일련의 λ³€μˆ˜ κ·Έλ£Ήν™” : (e.g., #775) legacy μ‹œμŠ€ν…œμ€ μ’…μ’… ν”„λ‘œκ·Έλž¨μ„ μž¬μ‚¬μš© ν•  수 μ—†κ²Œ λ§Œλ“œλŠ” μ „μ—­ λ³€μˆ˜λ₯Ό κ³Όλ„ν•˜κ²Œ μ‚¬μš©ν•©λ‹ˆλ‹€. μ‚¬μ†Œν•œ κ²½μš°μ™€ 같은 λŒ€λΆ€λΆ„μ˜ λ³€κ²½ 사항 κ°€λŠ₯ν•œ 경우 κΈ€λ‘œλ²Œ μ—…λ°μ΄νŠΈκ°€ ν•„μš”ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν”„λ‘œκ·Έλž˜λ¨ΈλŠ” μ „μ—­ λ³€μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ 전달해야 ν•  λ•Œ μ „μ—­ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. λ„ˆλ¬΄ λ§Žμ€ 맀개 λ³€μˆ˜λ₯Ό ν•¨μˆ˜μ— μ „λ‹¬ν•˜λ©΄ 호좜 μ‹œκ°„μ΄ κΈΈμ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

    이 λ¬Έμ œμ— λŒ€ν•œ 해결책은 격리 된 λ³€μˆ˜λ₯Ό κ·Έλ£Ήν™”ν•˜λŠ” 데이터 ꡬ쑰λ₯Ό μ •μ˜ν•˜κ³  ꡬ쑰에 λŒ€ν•œ 단일 μ°Έμ‘°λ₯Ό 맀개 λ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 refactoring은 κΈ°μ‘΄ λ³€μˆ˜λ₯Ό κ·Έλ£Ήν™”ν•˜μ—¬ ꡬ쑰λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. 참쑰에 μ˜ν•œ 맀개 λ³€μˆ˜μ— λŒ€ν•œ μ „μ—­ μ ‘κ·Ό λ³€ν™˜μ˜ 두 번째 뢀뢄은 λ¦¬νŒ©ν† λ§ "μ „μ—­ λ³€μˆ˜λ₯Ό 맀개 λ³€μˆ˜λ‘œ λ³€ν™˜"μ—μ„œ μ²˜λ¦¬λ©λ‹ˆλ‹€.

  • μΆ”μΆœ κΈ°λŠ₯: λ³΅μž‘ν•œ ν‘œν˜„μ΄λ‚˜ λ¬Έμž₯ λͺ©λ‘μ„ ν•¨μˆ˜ 호좜둜 λ°”κΏ‰λ‹ˆλ‹€. [Fowler 99]μ—μ„œ μ§€μ ν–ˆλ“―μ΄ 이것은 맀우 일반적인 λ³€ν˜•μž…λ‹ˆλ‹€. ν•¨μˆ˜κ°€ λ„ˆλ¬΄ κΈΈκ±°λ‚˜ λ³΅μž‘ν•΄μ§€λ©΄ μž‘μ€ 쑰각으둜 λ‚˜λˆ„κ³  각 쑰각을 ν•¨μˆ˜λ‘œ λ°”κΎΈκ³  더 짧은 ν•¨μˆ˜λ₯Ό ν•¨μˆ˜ 호좜둜 λŒ€μ²΄ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μΆ”μΆœ 된 μ½”λ“œκ°€ μŠ€μΊ”λ˜κ³  원본 ν•¨μˆ˜μ˜ μ§€μ—­ λ³€μˆ˜μ— λŒ€ν•œ 각 참쑰에 λŒ€ν•΄ 맀개 λ³€μˆ˜κ°€ μΆ”μΆœ 된 ν•¨μˆ˜μ— μΆ”κ°€λ©λ‹ˆλ‹€. I (@philix)λŠ” 더 이상 쒋은 refactoring νŒ¨ν„΄μœΌλ‘œ ν•¨μˆ˜ μΆ”μΆœμ„ ꢌμž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” (1) μƒˆλ‘œμš΄ ν•¨μˆ˜κ°€ 순수(https://en.wikipedia.org/wiki/Pure_function) μ΄κ±°λ‚˜ (2) 이미 μž¬μ‚¬μš©μ˜ ꡬ체적인 κ²½μš°κ°€μžˆμ„ λ•Œλ§Œ ν•¨μˆ˜λ₯Ό μΆ”μΆœν•΄μ•Όν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. John Carmack이 John Carmack in Inlined Codeμ—μ„œ 이 μ£Όμ œμ— λŒ€ν•΄ μ„€λͺ…ν•©λ‹ˆλ‹€.

  • 인라인 ν•¨μˆ˜

  • 쑰건식 톡합: μŠ€μœ„μΉ˜μ—μ„œ 인접 사둀λ₯Ό κ²°ν•©ν•˜μ‹­μ‹œμ˜€.

  • For into while

  • While into for

  • While into do while: while 문에 λŒ€ν•œ 쑰건을 μ—­μ „μ‹œν‚€λŠ” λ¬Έμž₯을 λ³€ν™˜ν•©λ‹ˆλ‹€.

Code Smells

μ½”λ“œ λͺ©λ‘μ—λŠ” ν•΄κ²°ν•  수 μžˆλŠ” 문제λ₯Ό λ‚˜νƒ€λ‚΄κ³  λ„€λΉŒ ν—Œλ‚©μžμ˜ λ§ˆμŒμ„ μ‚¬λ‘œ μž‘μ„ 수 μžˆλŠ” Jeff Atwood의 λƒ„μƒˆκ°€ λ‚©λ‹ˆλ‹€. 이 λͺ©λ‘μ€ 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°μ„ μœ„ν•΄ λ§Œλ“€μ–΄μ‘Œμ§€λ§Œ λŒ€λΆ€λΆ„ Cμ—μ„œ μ–΄λ–»κ²Œ μ μš©λ˜λŠ”μ§€λ₯Ό 보기가 μ–΄λ ΅μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Within Classes Code Smells (.c files)

  • Comments
  • Long Method (long functions)
  • Long Parameter List
  • Duplicated Code
  • Conditional Complexity
  • Combinatorial Explosion
  • Large Class (large .c files)
  • Type Embedded in Name
  • Uncommunicative Name
  • Inconsistent Names
  • Dead Code
  • Speculative Generality
  • Oddball Solution
  • Temporary Field (temporary global variable)

Code Smells Between Classes (between .c files)

  • Alternative Classes with Different Interfaces
  • Primitive Obsession #775
  • Data Class
  • Data Clumps
  • Refused Bequest
  • Inappropriate Intimacy
  • Indecent Exposure
  • Feature Envy
  • Lazy Class
  • Message Chains
  • Middle Man
  • Divergent Change
  • Shotgun Surgery
  • Parallel Inheritance Hierarchies
  • Incomplete Library Class
  • Solution Sprawl

C Refactoring 도ꡬ

Coccinelle

http://coccinelle.lip6.fr/

ν•  수 μžˆλŠ” 일에 λŒ€ν•œ μ˜ˆλŠ” # 690을 μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.