Refactoring : 구체적인 Refactoring 지침 CSharp

Code Complete 2nd Ed.에서 발췌한 것으로, 구체적인 Refactoring 지침을 몇가지 수준에서 설명한 글입니다.

데이터 수준
  • Magic Number를 명명된 상수로 대체한다.
  • 변수명을 보다 분명하고, 확정적으로 명명한다.
  • 표현식을 인라인(inline)으로 이동시킨다.
  • 표현식을 루틴으로 대체한다.
  • 중간변수를 사용한다. - 표현식의 목적을 표현하는 중간변수가 있으면 의미 파악이 쉽다.
  • 다목적으로 사용되는 변수를 단일 목적의 여러개의 변수로 변환
  • 로컬에서 사용하기 위한 목적이라면 매개변수 대신 지역 변수를 사용
  • 기본 데이터를 클래스로 변환
  • 타입 코드 집합을 클래스나 Enum으로 변환
  • 타입 코드 집합을 서브클래스를 갖는 클래스로 변환
  • 배열을 객체로 변환
  • 컬렉션을 캡슐화한다. - Reference type을 반환한다는 것은 캡슐화를 깬다. Readonly 형식으로 변환해서 제공한다.
  • 전형적인 레코드를 데이터 클래스로 대체한다.
명령문 수준
  • Boolean 표현식을 분해한다. - 설명적인 중간 변수를 사용하는 것이 가독성을 높힌다.
  • 복잡한 Boolean 표현식을 잘 명명된 Boolean 함수로 이동시킨다. - 표현식이 너무 복작하면, 메소드로 분리해라.
  • 서로 다른 조건문 내에 중복되는 코드를 결합한다.
  • 자신만의 루프 제어 변수를 예약어인 break이나 return를 사용하도록 한다.
  • 중첩된 if-then-else 명령문 내에서 리턴 값을 할당하는 대신, 답을 결정되었을 때 곧바로 리턴한다.
  • 조건문(특히, 반복되는 case 문)을 다형성으로 대체한다.
  • 널 값을 테스트 하는 대신, 널 객체를 생성하여 사용한다. - TimeSpan.Zero, String.Empty 같이

루틴 수준
  • 루틴을 추출한다./메소드를 추출한다. - 쪼개라
  • 루틴의 코드를 인라인으로 이동시킨다. - C# 은 제외
  • 긴 루틴을 클래스로 변환한다. 그리고 여러개의 루틴으로 분해한다.
  • 복잡한 알고리즘 대신 간단한 알고리즘으로 대체한다. (성능에 문제가 없다면)
  • 매개변수를 필요하다면 제거 또는 추가한다.
  • 변경연산으로부터 쿼리 연산을 분리한다.
  • 매개변수를 이용하여 유사한 루틴을 결합한다.
  • 전달되는 매개변수에 따라서 행동하는 루틴을 분리한다. - 매개변수에 따라 다른 코드를 실행한다면 메소드를 나누는게 좋다.
  • 특정한 필드 대신 전체 객체를 전달한다. - 매개변수 변화에 신경 쓸 게 없다.
  • 전체 객체 대신 특정 필드만 전달한다. - 메소드가 너무 단순해, 매개변수 변화가 없을 때
  • 다운캐스팅(downcasting)을 캡슐화한다. 

클래스 구현
  • Value Object 를 Reference Object로 변환한다. - 크거나 복잡하다면...
  • Reference Object를 Value Object로 변환 - 작고 간단하다면
  • 가상 루틴들을 데이타 초기화로 대체한다.
  • 멤버 메소드나 데이터의 위치를 변경한다. - 상속과 관련해서 슈퍼클래스로 옮기거나 서브클래스로 옮기거나
  • 특화된 코드는 서브클래스로 추출한다.
  • 유사한 코드를 슈퍼클래스로 결합한다.
클래스 인터페이스
  • 한 클래스를 두 개로 변환한다. - 클래스가 너무 많은 기능을 담당한다면 쪼개라. 클래스의 기능을 단순하게
  • 클래스를 제거하라 - 별 일 없는 클래스라면 응집력 높은 클래스로 결합해라
  • 위임(delegate)를 숨긴다 - 캡슐화
  • 미들 맨을 제거한다.
  • 상속을 위임으로 대체한다.
  • 위임을 상속으로 대체한다.
  • 외부 루틴을 소개한다.
  • 확장 클래스를 소개한다.
  • 노출된 멤버 변수를 캡슐화한다.
  • 가능하면 Readonly 필드로 해라
  • 클래스 외부로 노출할 루틴이 아닌 경우는 감춰라 - 캡슐화
  • 사용되지 않는 루틴을 캡슐화한다.
  • 슈퍼클래스와 서브 클래스의 구현이 매우 유사하다면 결합시켜라.
시스템 수준 
  • 제어할 수 없는 데이터를 위해 명확한 참조 소스를 생성한다. 
  • 필요하다면 단방향 클래스 관계를 양방향 클래스 관계로 바꾼다. 
  • 필요하다면 양방향 클래스 관계를 단방향 클래스 관계로 바꾼다.
  • 간단한 생성자 대신 팩토리(factory) 메소드를 제공한다.
  • IoC/DI를 활용한다.
  • 오류 코드를 예외로 대체하거나 그 반대로 한다. - 오류 처리 전략에 따른다.