- 리팩토링과 스멜 코드의 정의
- 리팩토링
: 소프트웨어를 보다 이해하기 쉽고, 적은 비용으로 수정할 수 있도록 겉으로 보이는 동작의 변화없이 내부 구조를 수정하는 것
- 스멜 코드
: 리팩토링을 수행할 때, 방해 요소가 되는 경우
- 코드 스멜의 유형
- 두 가지 이상의 이유로 수정되는 클래스 (Divergent Class)
→ 한 클래스가 두 가지 이상의 이유로 수정되면, 그 클래스는 한 가지 종류의 책임만을 갖는 것이 아니다.
⇒ 한 가지의 책임을 갖도록 수정한다.
- 여러 클래스를 동시에 수정 (Shotgun Surgery)
→ 특정 클래스를 수정할 때마다 관련된 여러 클래스들의 내부를 수정해야 한다.
⇒ 여러 클래스에 흩어진 유사 기능을 하나의 클래스에 모은다.
- 다른 클래스를 지나치게 애용 (Feature Envy)
→ 빈번히 다른 클래스로부터 데이터를 얻어와 기능을 수행한다.
⇒ 메소드를 그들이 애용하는 데이터가 있는 클래스로 옮긴다.
- 유사 데이터들의 그룹 중복 (Data Clumps)
→ 3개 이상의 데이터들이 여러 곳에 중복되어 나타난다.
⇒ 해당 데이터들은 독립된 클래스로 정의한다.
- 게으른 클래스 (Lazy Class)
→ 특정 클래스가 별로 사용되지 않는다.
⇒ 제거하거나 다른 클래스에 합병하고, 상속인 경우 상속을 없앤다.
- 지나친 일반화 (Speculative Genrality)
→ 지금 당장 필요하지 않은 기능을 미리 만들어 놓은 상속 관계
⇒ 상속 관계를 없앤다.
- 기본 데이터 타입 선호 (Primitive Obsession)
→ 객체 형태 그룹을 만들지 않고, 기본 데이터 타입만 사용
⇒ 같은 작업을 수행하는 기본 데이터의 그룹을 별도의 클래스로 만든다.
- 메시지 체인 (Message Chain)
→ 특정 객체를 사용하기 위해 많은 클래스를 거쳐야 한다.
⇒ 메시지 체인을 거치지 않고, 바로 사용할 수 있도록 한다.
- 미들 맨 (Middle Man)
→ 클래스가 가진 메서드 대부분이 다른 클래스에 책임을 넘긴다.
⇒ 미들 맨 역할의 객체를 제거한다.
- 부적절한 친밀성 (Inppropriate Intimacy)
→ 불필요하게 자신의 정보를 다른 클래스에게 노출하고, 다른 클래스에 국한된 정보를 알아내려고 한다.
⇒ 다른 클래스가 레퍼런스 유지를 못하게 하고, 이 클래스가 다른 객체의 정보를 알지 않고 기능을 수행할 수 있도록 한다.
- 상속을 거부 (Refused Bequest)
→ 상위 클래스의 속성과 메서드가 하위 클래스에서 사용되지 않는다.
⇒ 상위 클래스와 하위 클래스를 합친다.
- 리팩토링 기법
- 메서드 추출
: 그룹으로 함께 묶을 수 있는 코드 조각이 있으면 코드의 목적이 잘 드러나도록 메서드의 이름을 지어 별도의 메서드를 추출
- 클래스 추출
: 두 개의 클래스가 해야할 일을 하나의 클래스에서 담당하고 있는 경우, 새로운 클래스를 만들어 관련있는 필드와 메서드를 예전 클래스에서 새로운 클래스로 이동
- 서브클래스 추출
: 어떤 클래스가 일부 인스턴스에 의해서만 사용된다면 인스턴스만 사용하는 기능을 담당하는 서브 클래스를 만드는 작업
- 메서드 이동
: 메서드가 자신이 정의된 클래스보다 다른 클래스의 기능을 더 많이 사용하고 있는 경우, 메서드를 옮긴다.
- 인터페이스 추출
: 여러 클라이언트가 한 클래스의 인터페이스의 동일한 부분 집합을 사용하고 있다면, 부분 집합을 인터페이스로 뽑아내는 방법
- 템플릿 메서드 형성
: 각 서브 클래스에 있는 두 메서드가 완전히 같지 않지만, 비슷한 작업을 한다면 하나로 통일하여 상위 클래스로 옮긴다.
- 코드 품질 향상 기법
- 코드 인스펙션 : 눈으로 코드를 직접 보고 결함을 찾아내는 방법
- 정적 분석 : 프로그램 텍스트를 조직적으로 분석하여 결함을 찾아내는 방법
- 페어 프로그래밍 : 프로그래밍과 테스트를 담당하는 두 사람이 컴퓨터 머신을 공유하며 개발과 테스팅하는 방법