본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

조건문을 다형성으로 바꾸기

IT위키

조건문을 다형성으로 바꾸기(Replace Conditional with Polymorphism)는 객체의 타입이나 종류 코드에 따라 동작을 고르는 if-else·switch 분기를, 종류마다 하위 클래스를 두고 각 하위 클래스가 같은 메서드를 오버라이딩하게 바꾸는 리팩토링 기법이다.

마틴 파울러(Martin Fowler)의 리팩토링 카탈로그에 실린 기법이다. 카탈로그의 예는 새 종류(bird.type)에 따라 깃털 상태를 돌려주는 switch 문을, EuropeanSwallow·AfricanSwallow·NorwegianBlueParrot 클래스가 각자 plumage 를 구현하는 형태로 바꾼다.[1]

같은 타입 검사 분기가 여러 메서드에 흩어져 있으면 종류를 하나 더할 때마다 그 분기들을 모두 찾아 고쳐야 한다. 분기를 하위 클래스로 옮기면 새 종류는 새 하위 클래스 하나를 더하는 것으로 끝나고 기존 코드는 고치지 않아도 된다. 그래서 이 기법은 개방-폐쇄 원칙(OCP)을 지키게 해 준다.[2]

  1. 분기의 기준이 되는 종류마다 하위 클래스를 만든다. 상위 클래스가 아직 없으면 먼저 만들고, 객체를 만드는 곳은 팩토리로 모은다
  2. 조건문이 들어 있는 메서드를 상위 클래스에 남겨 두고, 한 분기씩 해당 하위 클래스의 오버라이딩 메서드로 옮긴다
  3. 분기를 옮길 때마다 테스트를 돌려 동작이 같은지 확인한다
  4. 모든 분기를 옮기면 상위 클래스의 메서드는 추상 메서드로 바꾸거나 기본 동작만 남긴다

바꾸기 전에는 상위 클래스 Player 의 stop() 이 종류 코드를 검사한다.

abstract class Player {
    abstract void play();
    void stop() {
        if (_type == VIDEO)       { /* 비디오 정지 */ }
        else if (_type == MUSIC)  { /* 음악 정지 */ }
        else                      { error(); }
    }
}

바꾼 뒤에는 VideoPlayer 와 MusicPlayer 가 각자 stop() 을 오버라이딩하고, 상위 클래스의 분기는 사라진다.

abstract class Player { abstract void play(); abstract void stop(); }
class VideoPlayer extends Player { void play() {...} void stop() { /* 비디오 정지 */ } }
class MusicPlayer extends Player { void play() {...} void stop() { /* 음악 정지 */ } }

호출하는 쪽은 player.stop() 만 부르고, 실제로 어떤 stop() 이 실행될지는 객체의 실제 타입이 정한다(동적 바인딩).

비슷한 리팩토링과 구별하기

편집 원본 편집
기법 하는 일 조건 분기와의 관계
조건문을 다형성으로 바꾸기 타입별 분기를 하위 클래스의 오버라이딩으로 옮긴다 분기 자체를 없앤다
메서드 인라인(Inline Method, Inline Function) 본문이 이름만큼 명확한 작은 메서드를 호출하는 곳에 풀어 넣고 메서드를 지운다. 메서드 추출의 반대 분기와 무관
다운캐스트 캡슐화(Encapsulate Downcast) 호출하는 쪽마다 하던 다운캐스트를 메서드 안으로 옮겨 구체 타입을 돌려준다(파울러 1판) 타입 검사를 없애지 않는다
생성자를 팩토리 메서드로 바꾸기(Replace Constructor with Factory Method) new 호출을 팩토리 메서드로 감싸 어느 하위 클래스를 만들지 한곳에서 고른다 생성 시점의 분기를 모을 뿐 동작 분기는 남는다
조건문 분해(Decompose Conditional) 복잡한 조건식과 각 분기 본문을 메서드로 추출한다 분기는 그대로 남는다

조건문을 다형성으로 바꿀 때 객체 생성 부분에는 생성자를 팩토리 메서드로 바꾸기를 함께 쓰는 경우가 많다. 그러나 동작 분기를 하위 클래스의 메서드로 옮기는 것은 조건문을 다형성으로 바꾸기이다.

쓰지 않는 편이 나은 경우

편집 원본 편집
  • 분기가 한 곳뿐이고 종류가 늘어날 일이 없으면 하위 클래스를 만드는 비용이 더 크다
  • 분기 기준이 객체의 종류가 아니라 실행 중 바뀌는 값(금액 구간, 날짜)이면 상태 패턴이나 전략 객체가 더 맞다
  1. ↑ Martin Fowler, 「Replace Conditional with Polymorphism」, Refactoring Catalog, https://refactoring.com/catalog/replaceConditionalWithPolymorphism.html, 확인일: 2026-11-04.
  2. ↑ 「Replace Conditional with Polymorphism」, Refactoring.Guru, https://refactoring.guru/replace-conditional-with-polymorphism, 확인일: 2026-11-04.