IT 끄적장

OOP - 피터 코드(Peter Coad)의 상속 규칙 본문

OOP

OOP - 피터 코드(Peter Coad)의 상속 규칙

kyunghoon_dev 2019. 11. 15. 18:59

Peter Coad는 상속의 오용을 막기 위해 상속의 사용을 엄격하게 제한하는 5가지의 규칙들을 만들었다.

만약, 다음 5가지 규칙에 위배되는 사항이 있으면 상속을 사용하면 안 된다고 말한다.

 

  1. 자식 클래스와 부모 클래스 사이는 '역할 수행 (Role Playing)'의 관계가 아니어야 한다.

  2. 한 클래스의 인스턴스는 다른 서브 클래스의 객체로 변환할 필요가 절대 없어야 한다.

  3. 자식 클래스가 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행해야 한다.

  4. 자식 클래스가 단지 일부 기능을 재사용할 목적으로 유틸리티 역할을 수행하는 클래스를 상속하지 않아야 한다.

  5. 자식 클래스가 "역할(role)", "트랜잭션(transaction)", "디바이스(device)" 등을 특수화해야 한다.

 

아래 그림은 사람이 직장인과 남편의 역할을 수행하는 것을 예로 만든 클래스 다이어그램이다.

이 클래스 다이어 그램을 바탕으로 피터코드의 5가지 규칙을 살펴보자.

  1. 자식 클래스가 부모 클래스의 역할 중 하나를 표현하는지?


    직장인은 어떤 순간의 사람이 수행하는 역할 중 하나다. 마찬가지로 남편 또한 어떤 순간에 사람이 수행하는 역할 중 하나다. 따라서 사람과 직장인이나 남편은 상속관계로 표현되어서는 안 되므로 규칙에 위배된다.


  2. 자식 클래스의 인스턴스들 사이에 변환관계가 필요한가?

    직장인은 어떤 시점에서 남편이 되어야 하고, 남편 또한 어떤 시점에서 직장인이 될 필요성이 있다.

    가령 직장인은 집에 돌아가면 남편의 역할을 수행해야 하며, 남편 또한 회사에 있을 때는 직장인의 역할을 수행해야 한다. 이러한 경우 객체의 변환 작업이 필요하므로 규칙에 위배되게 된다.

  3. 자식 클래스가 부모 클래스의 책임을 무시하거나 재정의하지는 않는지?
    이 부분은 사람, 직장인, 남편 클래스 등에 어떠한 속성과 연산이 정의되었는지 정보가 없으므로, 판단할 수 없는 부분이다.

  4. 기능만 재사용할 목적으로 상속관계를 표현하지는 않았는지?


    기능만 재사용할 목적으로 상속관계를 표현하지는 않았으므로 규칙을 준수한다.

  5. 자식 클래스가 역할, 트랜잭션, 디바이스 등을 특수화 하였는지?

    슈퍼 클래스에서 역할, 트랜잭션, 디바이스 등을 표현하지 않았기 때문에 규칙에 위배된다.

따라서 위의 다이어그램은 피터 코드의 규칙에 따라 상속을 사용하지 않아야 한다.

 

그렇다면 클래스 다이어그램을 다음과 같이 수정하면 어떠한 차이가 생길까?

 

 

처음에 작성한 클래스 다이어 그램은 사람의 역할이 직장인과 남편으로 고정되어 있다.

따라서 새로운 역할이 추가되면 '사람' 클래스 코드도 변경되어야 하는 문제점이 발생한다.

 

그러나, 새롭게 수정된 다이어그램은 '역할'이라는 추상 클래스를 상속받는 구조로 구체적인 역할 클래스들을 캡슐화하기 때문에 새로운 역할이 추가되더라도 '사람' 클래스의 코드는 영향을 받지 않는다.

 

 

위와 같이 기존 코드에 아무런 영향을 끼치지 않고 '학생'이라는 새로운 역할을 추가할 수 있는데. 이를 추후 학습할 SOLID 원칙의 OCP(개방 폐쇄의 원칙)라 한다.