Objects 10장 상속과 코드 재사용

카일·2020년 3월 2일
1

Objects 오브젝트

목록 보기
10/11
post-thumbnail

상속과 중복 코드

소프트웨어에서 중복은 악이다. 이러한 중복을 제거하는 가장 잘 알려진 방법은 상속이다. 사람들은 상속을 단순히 중복을 제거하기 위해 무분별하게 사용한다. 이러한 상속의 사용이 정말 중복을 제거하여 유지보수하기 좋은 코드를 만들까? 이는 다시 한번 생각해볼 필요가 있다.

중복을 제거하기 위해 상속을 사용하는 경우 부모 클래스와 자식클래스는 강하게 결합된다. 부모의 공용 인터페이스를 상속받을 뿐 아니라 인스턴스 변수 등 다양한 부모의 내부 동작을 자식은 알고 있어야 하며 이는 부모와 자식을 강하게 결합하게 만든다. 강하게 결합된 클래스의 단점은 무엇인가? 하나의 클래스가 변경될 때 다른 클래스도 변경을 야기한다. 중복을 제거하기 위해서 상속을 사용하였는데 상속에서 다시 중복의 문제점이 발생하는 것이다.

뿐만 아니라 부모 클래스의 특정부분을 오버라이딩 하는 것도 유의하여야한다. 부모 클래스가 명확하게 어떠한 형태로 동작하는지에 대해 알지 못하고 부모클래스를 사용하거나 오버라이딩하는 경우 예상치 못한 결과가 도래할 수 도 있다.

그렇다면 자식클래스는 부모클래스의 내부 구현에 대해 깊게 이해하고 이를 문서화하여 작업하는 방식이 바람직한 방식으로 떠오를텐데 말만 들어도 무엇인가 이상하지 않은가? 이를 해결하기 위해서는 추상화에 의존해야한다. 아래에서 알아보겠다.

취약한 기반 클래스

추상화에 의존한다는 말은 자식클래스가 부모클래스의 구현에 의존하는 것이 아니라 추상화에 의존하도록 변경해야 한다. 이를 위한 순서는 아래와 같다.

  • 두 메서드가 유사하게 보인다면 차이점을 메서드로 추출하라. 메서드 추출을 통해 두 메서드를 동일한 형태로 보이도록 만들 수 있다.
    • 추출된 메서드는 추상 클래스의 일부로 변경하여라. 부모와 자식이 공통적으로 갖는 부분에 대해서 추상클래스에서 구현하고 부모와 자식이 다른 부분에 대해서는 공통적으로 갖는 부분이 호출할 수 있도록 추상클래스내에 정의하고 이를 오버라이딩 하는 방식으로 사용하여라.
  • 부모 클래스의 코드를 하위로 내리지말고 자식 클래스의 코드를 상위로 올려라. 부모 클래스의 구체적인 메서드를 자식 클래스로 내리는 것보다 자식 클래스의 추상적인 메서드를 부모 클래스로 올리는 것이 재사용성과 응집도 측면에서 더 뛰어난 결과를 얻을 수 있다.

이렇게 하는 경우 최상위 추상 클래스에서는 부모와 자식이 공통적으로 담고 있는 부분을 정의하기 때문에 그 부분이 수정되면 최상위 추상 클래스만 수정하면 된다. 반대로 부모와 자식은 각기다른 형태로 추상 메서드를 정의하고 있기 때문에 각자의 역할이 변경되면 각자 수정하면 된다. 즉 하나의 변경사항에 대해서만 변경이 이루어지며 결합도가 낮아진다는 의미이다.

하지만 이런 경우는 어떨까? 부모와 자식 모두에게 적용되는 추가적인 기능이 존재할 때 이를 최상위 추상 클래스가 인스턴스로 갖게 되는 경우는 모든 객체가 수정을 해야한다. 즉 상속은 어떠한 형태로든 자식과 부모를 결합시킨다. 이를 완전히 제거할 수 있는 방법은 존재하지 않는다.

개인적인 결론으로는 상위 개념으로서 부모클래스나 인터페이스는 최대한 변경의 가능성이 적다는 확신을 가지고 만들어야한다. 상위 개념에서의 변화는 필연적으로 하위 객체들에게 영향을 미친다. 따라서 추상화를 할 때 상위 개념에 대해 명확하게 정의하는 것이 바람직하다.

차이에 의한 프로그래밍

상속과 같이 기존 코드와 다른 부분만을 추가함으로써 애플리케이션의 기능을 확장하는 방법을 차이에 의한 프로그래밍이라고 부른다. 객체지향 세계에서 중복 코드를 제거하고 코드를 재사용할 수 있는 가장 유명한 방법은 상속이다. 상속은 분명히 중요한 개념이고 효용을 가지고 있지만 단순히 중복의 제거의 목적으로 사용하는 것은 바람직하지 않다. 즉 잘 추상화된 상위개념아래에 차이에 의해 각 계층의 기능을 정의하였을 때 하나의 타입으로 다양한 기능을 제공하는 추상화된 형태로 사용될 수 있다.

0개의 댓글