마틴 파울러의 책 'Refactoring'에 소개된 '코드의 악취(Bad smells in code)'에 대해 알아보겠습니다.
'중복된(Duplicated) 코드'는 같은 소스 코드가 여기저기 쓰인 경우입니다.
'너무 긴 메서드(Long method)'는 메서드의 소스가 너무 긴 경우입니다.
긴 메서드는 피해야 할 습관입니다.
메서드 소스가 길고 장황하다는 것은 메서드가 하나의 역할만 하지 않는다는 말입니다. 간단한 + 같은 수식을 메서드로 빼라는 말이 아니라 메서드가 하는 역할은 하나만 해야 하는 것을 말합니다. 트랜잭션을 처리하는 메서드의 경우 길게 작성되는 경우를 종종 보게 됩니다.
그렇게 작성된 메서드보다는 역할에 따라 명확하게 분리하여 트랜잭션 메서드에 엮는 것이 좋은 방법입니다.
'거대한 클래스(Large clasS)'는 클래스의 파일이나 메서드가 너무 많은 경우입니다.
참 어렵습니다. 너무 길어서도 너무 많아서도 안 되니 말입니다. 항상 개발자는 원자성과 복잡성을 동시에 다루는 직업입니다. 이 둘 사이에서 중심을 잡는 일이죠.
'너무 많은 인수(Long parameter list)'는 메서드에 전달하는 파라미터가 너무 많은 경우입니다.
이런 경우 데이터 객체를 사용하여 파라미터를 조정합니다.
'변경의 발산(Divergent change)'는 사양 변경이 발생할 경우 수정할 곳이 여기저기에 흩어져 있음을 나타냅니다.
'변경의 분산(Shotgun surgery)'는 어떤 클래스를 수정하면 다른 클래스도 수정해야 하는 경우를 말합니다.
'속성, 조작의 부적절 관계(Feature envy)'는 다른 클래스의 속성을 건드리는 경우입니다.
객체가 다른 객체의 속성을 직접 다루는 것보다는 메서드를 통해 해당 객체에게 명령을 내리는 것이 집합도를 줄이는 방법입니다.
'데이터 덩어리(Data clump)'는 여러 데이터들이 하나의 객체에 정리되어 있는 경우입니다.
'기본 데이터형의 집착(primitive obsession)' 클래스를 만들지 않고 int형과 같은 기본 데이터만 사용하는 경우입니다.
'switch 문(switch statement)'는 if문이나 switch문을 사용하여 분기 처리하는 것을 말하는데 이 건은 객체 지향과 절차 지향 언어의 특성을 잘 이해하고 적용하시면 됩니다.
'평형 상속 구조(Parallel inheritance hierarchies)'는 서브 클래스를 만들면 다른 클래스에도 서브 클래스를 만들어야 하는 경우입니다.
무분별한 상속을 지양해야 한다는 말입니다.
'게으름뱅이 클래스(Lazy class)'는 클래스가 하는 일이 별로 없는 경우입니다.
이런 경우 클래스를 제거하고 메서드로 변경할 수 있는지 확인해봅니다.
'추측성 일반화(Sepculative generality)'는 미리 만드는 코드로 실제 사용되지 않는 코드들을 말합니다.
참조 관계(소스가 사용되는 부분)가 하나도 없다면 과감하게 삭제해도 괜찮습니다.
'일시적 속성(Temporary field)'는 객체의 변수가 특정한 상황에서만 사용되는 경우입니다.
이런 변수들은 소스의 복잡성을 올리기 때문에 별도로 관리하는 방법을 고민해야 합니다.
'메시지의 연쇄(Message chains)'는 메서드가 호출하는 경로가 복잡한 것을 말합니다.
메서드가 호출하는 경로가 계속해서 연결되는 경우입니다. 경로를 단순화시키는 것이 필요합니다.
'중개자(Middle man)'는 자신이 하는 일이 적고 다른 메서드를 호출해 해당 메서드가 대부분의 일을 수행하는 경우입니다. 통합을 고려해 볼 만합니다.
'부적절한 관계(Inapproriate intimacy)'는 쌍방향 링크가 걸려 있거나 잘못된 상속 관계를 나타냅니다.
'클래스 인터페이스 불일치(alternative classes with different interface)'는 기능은 같은데 메서드명이 다른 경우입니다.
'데이터 클래스(Data class)'는 필드와 getter와 setter만 있는 클래스를 말합니다.
getter와 setter는 참 논쟁이 많은 부분입니다. 우선 마틴 파울러는 이런 클래스는 불필요한 클래스로 인식했네요.
'미숙한 클래스 라이브러리(Incomplete library class)'는 사용하기 어려운 클래스 라이브러리를 말합니다.
사용하기 어렵다는 것은 설계의 문제입니다. 라이브러리는 사용하기 편하게 작성되어야 합니다.
'상속 거부(Refused Bequest)'는 하위 클래스에서 상속받은 메서드를 호출하면 문제가 발생하거나, 방치되는 속성 및 메서드를 말합니다.
'코멘트(Comments)'는 코드의 부족을 보충하기 위해 상세한 코멘트를 말합니다.
주석도 참 정답이 없는 어려운 부분입니다. 요즘은 TFS나 Source safe 같은 소스 버전을 관리하는 툴을 사용해도 수정 주석이나 개발 목록 주석을 남기는 경우가 허다합니다. 그리고 설명 주석을 의무적으로 남기게 하는 경우도 많이 있죠.
아마도 개발자 간의 실력 차이가 있기 때문에 그렇다고 생각합니다.
주석이 사라지게 작성하는 것이 가장 좋지만 개발자 간의 실력 차이나 환경 문화도 극복해야 하는 과제입니다.
'IT > 아키텍처' 카테고리의 다른 글
결합도(Coupling)과 응집도(Cohesion) (0) | 2022.07.13 |
---|---|
객체 설계의 원칙(SOLID) (0) | 2022.07.04 |
리팩터링(Refactoring) (0) | 2022.06.24 |
네이밍 룰 - 메소드 [2편, 단어] (0) | 2022.05.26 |
네이밍 룰 - 메서드 [1편, 기본편] (0) | 2022.05.26 |
댓글