본문 바로가기

공부기록/객체지향

오브젝트 10장 - 상속과 코드 재사용

전통적인 패러다임 → 코드를 재사용하는 방법은 코드를 복사한 후 수정하는 것

객체지향 패러다임 → 상속 또는 합성

10장에서는 상속, 11장에서는 합성에 대해 설명함

상속과 중복코드

중복코드 → 혼란야기 + 동료들을 의심하게 만든다

DRY 원칙

중복 코드는 변경을 방해한다. 중복 코드는 코드를 수정하는 데 필요한 노력을 몇 배로 증가시킨다.

DRY원칙 = Don’t Repeat Yourself ⇒ 동일한 지식을 중복하지 마라

중복과 변경

책의 예제 코드 → 요구사항 변경으로 새로운 기능이 추가됨 → 상속으로 코드 중복을 줄임

상속을 위한 경고 1

→ 자식 클래스의 메서드 안에서 super 참조를 이용해 부모 클래스의 메서드를 직접 호출할 경우 두 클래스는 강하게 결합된다. super 호출을 제거할 수 있는 방법을 찾아 결합도를 제거하라.

→강하게 결합될 경우 부모 클래스의 변경에 의해 자식 클래스가 영향을 받는다.

취약한 기반 클래스 문제

부모와 자식의 강한 결합 → 부모 클래스의 작은 변경에도 자식 클래스는 컴파일 오류와 실행 에러.

부모 클래스의 변경에 의해 자식 클래스가 영향을 받는 현상 → 취약한 기반 클래스 문제

상속 → 자식 클래스를 점진적으로 추가하여 기능을 확장하는 데는 용이하지만, 높은 결합도로 인해 부모 클래스를 점진적으로 개선하는 것은 어렵게 만든다.

자식 클래스가 부모 클래스의 구현 세부사항에 의존하도록 만들기 때문에 캡슐화를 약화시킨다. 상속은 코드 재사용을 위해 캡슐화의 장점을 희석시키고, 구현에 대한 결합도를 높임으로써 객체지향이 가진 강력함을 반감시킨다.

불필요한 인터페이스 상속 문제

vector를 참조하여 만든 Stack

vector에는 기능이 더 많은데, Stack은 이것을 상속받아 만들었다.. 그래서 vector에 있는 인터페이스를 stack에서도 사용할 수 있다.

인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 만들어야 한다.

HashTable과 properties, properties는 String만 key 타입으로 받을 수 있는 map인데, 상속을 사용하여 개발되어, hashTable에 있는 인터페이스를 사용할 수도 있었다. 그러면 String이 아닌 key값도 사용할 수 있었음.. .

상속을 위한 경고2

→ 상속받은 부모 클래스의 메서드가 자식 클래스의 내부 구조에 대한 규칙을 깨트릴 수 있다.

메서드 오버라이딩의 오작용 문제

상속받은 메서드가 잘못 작용할 수 있다. 그리고 정상적으로 작동한다 하더라도, 나중에 부모 클래스가 수정되면서 문제가 발생할 수 있다.

상속을 위한 경고3

  • 자식 클래스가 부모 클래스의 메서드를 오버라이딩할 경우 부모 클래스가 자신의 메서드를 사용하는 방법에 자식 클래스가 결합될 수 있다.

→ 결국 내부 구현을 문서화해야 하는데, 이것을 문서화하는게 객체지향의 핵심이 구현을 캡슐화하는 것인데...

→ 결국 상속이 캡슐화를 위반함으로써 초래되는 불행...

설계는 트레이드 오프 활동. 상속으로 코드 재사용을 줄였지만, 캡슐화를 희생한다.

부모 클래스와 자식 클래스의 동시 수정 문제

부모 클래스를 수정할 때 자식 클래스도 같이 수정해야할 수도 있음

상속을 위한 경고4

  • 클래스를 상속하면 결합도로 인해 자식 클래스와 부모 클래스의 구현을 영원히 변경하지 않거나, 자식 클래스와 부모 클래스를 동시에 변경하거나 둘 중 하나를 선택할 수 밖에 없다.

Phone 다시 살펴보기

추상화에 의존하자

  • 두 메서드가 유사하게 보인다면 차이점을 메서드로 추출하라. 메서드 추출을 통해 두 메서드를 동일한 형태로 보이도록 만들 수 있다.
  • 부모 클래스의 코드를 하위로 내리지 말고 자식 클래스의 코드를 상위로 올려라. 부모 클래스의 구체적인 메서드를 자식 클래스로 내리는 것보다 자식 클래스의 추상적인 메서드를 부모 클래스로 올리는 것이 재사용성과 응집도 측면에서 더 뛰어난 결과를 얻을 수 있다.

차이를 메서드로 추출하라

변하는 것으로부터 변하는 것을 분리하라

변하는 부분을 찾고 이를 캡슐화하라

중복 코드를 부모 클래스로 올려라

abstact class를 만들고, 중복코드를 거기에 포함

변하는 부분을 각자 구현하도록 함

추상화가 핵심이다

의도를 드러내는 이름 선택하기

차이에 의한 프로그래밍

기존 코드와 다른 부분만을 추가함으로써 애플리케이션의 기능을 확장하는 방법을 차이에 의한 프로그래밍이라고 부른다.

상속이 코드 재사용이라는 측면에서 매우 강력한 도구인 것은 사실이지만 강력한 만큼 잘못 사용할 경우에 돌아오는 피해 역시 크다는 사실을 뼈저리게 경험.

(상속 → 다형성 외에 장점이 거의 없는 듯 하다. ⇒ 다형성 차이를 적는 부분, 또는 일부 디자인 패턴. Composite같은 것은 자기자신을 계속... 이런것도 결국 다형성이 장점인가?? 확인 필요..)