프로그램 아키텍쳐/Refactoring

코드의 악취(Bad Smells in Code)

본클라쓰 2010. 12. 9. 11:48

 

코드의 악취는 마틴 파울러의 책 'Refactoring'에 쓰여진 비유로 리팩토링이 필요한 부분을 지칭합니다. 마틴 파울러는 책에서 코드의 악취를 22가지 소개하고 있습니다.

 

영문   한글  설명
 Duplicated Code  중복된 코드   코드가 여기저기 겹쳐 있다.  
 Long Method   너무 긴 메소드   메소드가 너무 길다. 
 Large Class  거대한 클래스   클래스의 파일이나 메소드가 너무 많다.  
 Long Parameter List  너무 많은 인수   메소드에 전달하는 파라미터가 너무 많다.  
 Divergent Change  변경의 발산   사양 번경이 발생한 경우 수정할 곳이 여기 저기 흩어져 있다.  
 Shotgun surgery  변경의 분산   어떤 클래스를 수정하면 다른 클래스도 수정해야 한다.  
 Feature Envy  속성, 조작의 부적절관계  언제나 다른 클래스의 속성을 건드리고 있다.
 Data Clump  데이터 덩어리  정리해서 다룰 수 밖에 없는 여러 개의 데이터가 하나의 클래스에 정리되어 있다.
 Primitive Obsession  기본 데이터형의 집착   클래스를 만들지 않고 Int형과 같은 기본 데이터형만 사용한다.  
 switch 문  switch 문  스위치문이나 If 문을 사용해 분기한다.  
 Parallel Inheritance Hierarchies  평형 상속 구조  서브 클래스를 만들면 클래스 계층에 따로 서브 클래스를 만들어야 한다.
 Lazy Class  게이름뱅이 클래스  클래스가 하는 일이 별로 없다.  
 Speculative Generality  추측성 일반화  언제가는 이렇게 확장하겠지 하고 기대하는 지나친 일반화
 Temporary Field  일시적 속성  일시적으로 사용하는 필드가 있다.
 Message Chains  메시지의 연쇄  메소드가 호출하는 연쇄가 너무 많다.
 Middle man  중개자  자신이 하는 일이 없는 클래스가 있다.
 Inappropriate Intimacy  부적절한 관계   필요없는 쌍방향 링크가 걸려 있거나 is-a 관계가 아니면서 상속을 사용한다.  
 Alternative Classes with Different Interface  클래스의 인터페이스 불일치  API가 부적절하다.
 Incomplete Library Class  미숙한 클래스 라이브러리   기존의 클래스 라이브러리를 사용하기 힘들다.
 Data Class  데이터 클래스  필드와 getting 메소드와 setting 메소드만 가지고 있는 클래스가 있다.
 Refused Bequest  상속 거부   상속하고 있는 메소드면서 그것을 호출하면 문제가 발생한다.  
 Comments  코멘트  코드의 부족을 보충하기 위해 상세한 코멘트가 있다.

 

 

마틴 파울러는 이와 같이 코드의 악취를 규정하였습니다.

 

이 부분에 대해 관점의 차이가 존재합니다. 주석의 경우 어느 정도 주석이 필요하다고 생각되면 주석을 다는 것도 좋습니다. 이런 문제는 개발자마다의 관점의 차이일 뿐입니다. 개인적으로도 구현 주석을 필요 없다해도 설명 주석은 필요하다고 생각합니다. 물론, 구현을 이해하지 못하는 사람을 위해 필요한 경우 주석을 사용하는 것도 필요합니다. 즉, 개발시 자신에게 맞는 관점을 찾는 것이 중요합니다. 

 

 

 

코드의 악취 대처 방법

 

코드의 악취에 대처하는 방법은 다음과 같습니다.

 

 

1. 겹쳐 있는 코드

 

비슷한 코드가 여기 저기 산재해 있다면 수정하기가 어렵습니다. 버그가 발견되면 여러 곳을 고쳐야 하기 때문입니다. 이럴 땐 겹쳐 있는 코드를 찾아 메소드 추출이나 클래스 추출이라는 리팩토링을 검토하는 것이 좋습니다. 또한 Null 체크가 여기 저기 발견된다면 Null 오브젝트를 도입해 보는 것이 좋습니다. 오류 체크가 많은 경우 오류 코드를 예외로 치환해 보는 것을 검토하는 것도 좋습니다.

 

2. 너무 긴 메소드

 

메소드가 너무 길면 이해하기 어렵습니다. 따라서 긴 메소드를 발견하면 메소드 추출이라는 리팩토링을 하는 것이 좋습니다. 또한 클래스가 하는 일이 너무 만다면 책임들을 나눠 클래스를 추출하는 리팩토링을 검토하는 것이 좋습니다. 너무 길다면 짤게 하고 너무 크다면 작게 하는 게 리팩토링의 기본입니다.

 

3. 너무 많다

 

클래스가 너무 크다고 클래스의 추출을 지나치게 많이 하면 안 됩니다. 클래스의 추출을 지나치게 하면 이번에는 클래스가 너무 많아져 버립니다. 아무리 책임을 줄이는 것이 좋다고 하더라도 일에는 정도가 있는 것입니다. 커다란 클래스는 이해하기 어렵지만 클래스의 수가 너무 많은 것도 이해하는데 지장을 줍니다. 클래스가 너무 많다고 느껴진다면 중개자의 삭제라는 리팩토링이나 클래스의 인라인화 또는 메소드의 인라인화 등의 리팩토링을 검토해 봅니다.

 

4. 이름 표현이 어울리지 않는다.

 

표현하고 싶은 개념과 이름이 어울리지 않는다는 것을 발견하면 영향을 끼치는 범위를 최소한으로 하고 이름을 변경해야 합니다. 메소드명의 변경은 대표적인 리팩토링입니다.

 

5. 지나치게 공개했다.

 

메소드만이 아니고 필드 역시 너무 많이 공개해서는 안 됩니다. 필드의 캡슐화라는 리팩토링으로 필드를 감춥니다. 또한 클래스 이름 역시 너무 많이 공개해서는 안 됩니다. 'new' 키워드를 사용해 인스턴스를 생성할 때는 구체적인 클래스명을 씁니다. 이 경우 클래스명을 변경하는 것이 어렵습니다. 왜냐하면 프로그램에 인스턴스를 생성하는 부분 모두 변경해야 하기 때문입니다. 이런 경우 생성자를 Factory Method로 치환하는 것을 검토해야 합니다.