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