티스토리 뷰

일단 뜨겁게 청소하라.

"리팩토링이 뭔가요?"

"일정이 너무 촉박해서 리팩토링할 시간이 없어요."

"무엇을 리팩토링해야 할지 모르겠습니다"

"어떻게 리팩토링해야 할지 모르겠습니다"

리팩토링은 개발자의 코딩 능력을 향상시키는 좋은 습관이며 훈련입니다. 

이런 반복적인 훈련과 습관이 개발자의 내공입니다.  


리팩토링이라고 하면 어렵게 생각하는 사람도 있고 또 언제해야할 지 무엇을 어떻게 해야 할지 모르는 사람이 많습니다.

이에 대해 간단히 정리해 봤습니다.   

1. 리팩토링이 뭐에요?

리팩토링을 정의하는 말들 


겉으로 보이는 동작의 변환없이 내부 구조를 개선하는 것

- 마틴 파울러




작동하는 깔끔한 소스(Clean Code)


비야네 스트롭스트룹(Bjarne Stroupstrup)

우아하고 효율적인 코드, 의존성을 최대한 줄이고 성능을 최적으로 유지하며 Clean Code는 한가지를 제대로 한다

 

그래디 부치

Clean Code단순하고 직접적이다

Clean Code는 잘 쓴 문장처럼 읽힌다

Clean Code는 설계자의 의도를 숨기지 않으면 명쾌한 추상화와 단순한 제어문으로 가득하다

 

데이브 토마스 

Clean Code읽기 쉽고 고치기 쉽다

Clean Code에는 의미 있는 이름이 붙는다


"깨진 유리창 법칙"

"만일 한 건물의 유리창이 깨어진 채로 방치되어있다면 다른 유리창들도 곧 깨어질 것이다


잘못된 코드를 방치하면 그 코드가 순식간에 여기 저기 복제되어 퍼져 나간 것을 볼 수 있습니다. 

A : "아니 이걸 왜 이렇게 짠거에요?"

B : "제가 짠게 아니고 기존에 있던거 가져다 쓴거에요" 

C : "제가 그런거 아닌데요"

D : "일정이 촉박해서 일단 복사해서 썼습니다."

잘못된 소스는 최우선적으로 수정하는게 좋습니다. 


"보이스카우트 규칙"

"캠프장에 처음 왔을 때보다 더 깨끗하게 떠나라" 


"리팩토링은 언제해야 할까?"라는 질문에 대한 답이 되지 않을까 싶습니다.

2. 리팩토링은 언제할까?

1. Rule of Three 

삼진 아웃제와 비슷합니다. 비슷하거나 동일 코드가 두번 이상  발생하게 되면 세번째에는 리팩토링을 해야할 때인 겁니다. 

2. 새로운 기능을 추가할 때

리팩토링은 다른 사람의 코드를 이해하는데 도움을 줄 뿐만 아니라 새로운 기능을 추가, 수정 하기 쉽게 해줍니다. 

3. 버그 수정할 때  

리팩토링 과정에서 버그를 쉽게 발견할 수도 있고 수정하기도 용이해 집니다. 

4. 코드 리뷰할 때

코드 리뷰를 하면서 더 나은 코드로 리팩토링할 수 있습니다. 


개념 상 네가지로 분류를 했을 뿐 실 업무를 처리할 때는 해당 소스를 추가 및 수정할 때 무조건 해야 한다고 보면 맞습니다. 


리팩토링은 항상, 지속적으로 또 자기가 만든 코드가 아니더라도 해야합니다.  

리팩토링할 때 자기 코드만 할려고 하는 경향이 있습니다. 이전 개발자에게 물어 보기도하고 동의를 구하는 과정도 중요합니다. 굉장히 귀찮은 일이 될 수 있지만 혼자 개발하는 것이 아니라면 가장 중요한 부분입니다. 서로 자기 방식대로 자기 스타일대로 코딩을 하는 것을 막아야 합니다. 

리팩토링은 항상해야 합니다. 또 1회만 하는게 아닙니다. 지속적으로 수행해야 합니다. 

3. 무엇을 리팩토링해야 하는가? 

코드의 악취

  • 중복코드(Duplicated Code)
  • 너무 긴 메소드(Long Method)
  • 거대한 클래스(Large Class)
  • 너무 많은 인수(Long Parameter List)
  • 변경의 발산(Divergent Change)
  • 변경의 분산(Shotgun Surgery)
  • 속성, 조작의 부적절한 관계(Feature Envy)
  • 기본 데이터형의 집착(Primitive Obsession)
  • 추측성 일반화(Speculative Generality)
  • 일시적 속성(Temporay Field)
  • 메시지 연쇄(Message Chains)
  • 중개자(Middle Man)
  • 클래스의 인터페이스 불일치

내 코드는 설명 가능한가?

코드를 보고 다른 사람에게 설명해 보세요.  그러면 그 코드가 리팩토링 대상인지 아닌지 알 수 있습니다. 
클린코드는 쉽게 읽히고 이해할 수 있어야 합니다. 
주저리 주저리 나열해 놓은 글은 읽는 사람이 무슨 내용인지 알기 어렵습니다. 
설계를 하고 코드를 작성한 것과 생각난대로 그냥 코딩해 놓은 것은 한눈에 봐도 차이가 납니다. 
일단 어떤 처리를 할지 정의를 하고(추상화) 그에 따라 코드를 정리한다면 나중에 추가/수정이 용이해지고 재사용이 가능해집니다. 더불어 테스트도 가능한 코드가 됩니다.  

내 코드는 테스트 가능한가? 

테스트는 입력 값과 결과가 명확해야 하며 테스트하고자 하는 의도가 분명해야 합니다. 
테스트가 필요한 부분임에도 불구하고 해당 부분을 테스트 할 수 없고 전체를 테스트해야 한다면 리팩토링이 필요하다는 것을 알 수 있습니다. 모든 리팩토링은 동일 결과물을 만들어야 하고 그것을 증명해야 해야합니다. 모든 테스트 케이스를 만들 수 없다고 해도 필요시 해당 부분을 테스트 가능하게 만들어야 합니다. 

내 코드는 규칙/표준을 준수하였는가? 

클래스명, 변수명, 표기법, URI, 처리 방법 등이 프로젝트에서 정의한 표준을 지키지 않았다면 수정해야 합니다. 
클래스명, 변수명 등 적절한 이름을 짓는 것은 굉장히 피곤한 일입니다. 잘못된 이름은 자칫 무개념 개발자로 찍힐 수도 있습니다. 
경험상 이름 때문에 전체를 리팩토링한 경우도 상당히 많았습니다.

잠재적 오류/ 품질향상을 위한 리팩토링 

Data/Time/Configuration 등에 따른 로직 추가/수정. 
NullpointException, ArrayIndexOutOfBoundException, InputSteam close 처리, Thread Safe 등  
성능향상, 캐시를 고려한 설계, String/StringBuffer/StringBuilder, HashMap/HashTable, List/Vector/Array 
SonarQube 등 정적 분석툴을 이용한다. 

4. 어떻게 리팩토링을 할까?

이제 가장 중요한 문제인 어떻게?라는 이슈에 당면했습니다. 
리팩토링을 좀 더 구체적으로 표현하자면 
"추가와 수정이 용이한 구조를 만들고 가독성을 높이며 중복을 제거하는 일련의 작업"
이라 할 수 있습니다. 
별거 아닌 거 같지만 막상 할려면 쉽지 않은 내용입니다. 
설명만으로는 쉽지않은 내용이라 실제 예제를 하나씩 하나씩 추가하는 방식으로 풀어보겠습니다.
주요 방법은 SonarQube를 활용했습니다.  

2019/01/02 - [리팩토링(스프링기반)] - Use try-with-resources or close this "BufferedInputStream" in a "finally" clause

2019/01/07 - [리팩토링(스프링기반)] - Java class, method 선언 시 표현 순서

2019/01/07 - [리팩토링(스프링기반)] - 타입 선언은 인터페이스로 하자

2019/01/07 - [리팩토링(스프링기반)] - 오브젝트 복제하기

2019/01/08 - [리팩토링(스프링기반)] - Map 전체 내용을 읽을 때 Key, Value를 모두 사용한다면 "entrySet"을 사용하라

2019/01/08 - [리팩토링(스프링기반)] - 동일 처리를 하는 catch문 합치기

2019/01/08 - [리팩토링(스프링기반)] - private 생성자 추가

2019/01/08 - [리팩토링(스프링기반)] - java.nio.Files을 이용한 파일 삭제



참고

Books

Clean Code, 로버트 C 마틴

Refactoring, 마틴파울러


Sites

https://refactoring.guru/refactoring

댓글
댓글쓰기 폼