Skip to content
DarkKaiser의 블로그
DarkKaiser의 블로그
  • 개발 관련 자료(노션)
  • Raspberry Pi(노션)
  • WD My Cloud(노션)
  • GitHub
DarkKaiser의 블로그

상속과 합성

DarkKaiser, 2007년 7월 16일2023년 8월 30일

‘Gof의 디자인 패턴’에서는 “Favor object composition over class inheritance”라고 말한다. 이를 해석하면 “객체 합성이 클래스 상속보다 더 나은 방법이다”라는 의미이다.

객체지향 시스템에서 기능의 재사용을 위한 가장 대표적인 두 가지 방법이 상속과 합성이다. 디자인 패턴에서는 상속을 통한 재사용을 ‘white-box reuse’라고 하고 합성을 통한 재사용을 ‘black-box reuse’라고 한다.

먼저, 상속에 대해 살펴보자. 우리가 어떤 객체를 상속하면 private으로 선언되지 않은 모든 변수와 메서드, 생성자가 하위클래스에 노출된다. 이렇게 하위클래스에서 수퍼클래스의 내부가 보인다는 의미로 디자인 패턴에서는 상속을 통한 재사용을 ‘white-box reuse’라고 말하는 것이다. 투명한 하얀 상자 안에 어떤 것이 들어있다면 우리는 밖에서 그것을 볼 수 있을 것이다.

상속의 장점은 오버라이딩을 통해 수퍼클래스의 구현을 손쉽게 재정의할 수 있다는 것이다. 그럼에도 불구하고 상속을 이용해서 재사용할 때, 시스템 설계자들은 무엇을 못마땅하게 여길까?

세 가지 이유가 있는데, 하나는 앞서 말했듯이 수퍼클래스가 하위클래스에 불필요하게 많은 부분이 노출된다는 것이다. 이것은 객체지향의 원칙 중 하나인 캡슐화에 위배되고 또한 하위클래스가 수퍼클래스의 구현에 종속되고, 수퍼클래스 구현이 변경되어야 할 경우가 생기면 하위클래스도 변경해야 하는 문제점이 발생할 수 있다.

또 다른 하나는 컴파일 시점에 객체의 형식이 이미 결정된다는 것이다. 사실 이것이 가장 큰 이유기도한데, “A 클래스가 B 클래스의 수퍼클래스다”라는 식의 정보가 이미 컴파일 시점에 결정되어 버리기 때문에 런타임 시점에서 상속받은 수퍼클래스의 구현을 변경할 수 없어 시스템의 유연성이 떨어진다는 단점이 생긴다.

마지막 하나는 시스템이 진화할수록 상속 관계가 복잡해져서 그 시스템의 상속 트리를 정확하게 이해하고 있지 않으면 시스템의 수정과 확장에 손을 댈 수 없는 상황까지 발생할 가능성이 생기기 때문이다.

지금까지 상속의 단점에 대해서만 너무 부각시킨 느낌이 든다. 하지만 상속은 분명 객체지향 프로그래밍에서 가장 중요한 개념 중 하나고 그 장점과 유용성도 많다.

이제 합성에 대해 알아보자. 객체 합성은 객체가 다른 객체의 참조자를 얻는 방식으로 런타임시에 동적으로 이뤄진다. 따라서 다른 객체의 참조자를 얻은 후 그 참조자를 이용해서 객체의 기능을 이용하기 때문에 해당 객체의 인터페이스만을 바라보게 됨으로써 캡슐화가 잘 이뤄질 수 있다. 이렇게 각 객체의 캡슐화를 유지할 수 있기 때문에 시스템 설계자들이 상속보다 합성을 더 선호하는 것이다. 또한 합성이 상속과 달리 참조 객체의 내부를 볼 수 없기 때문에 디자인 패턴에서 “black-box reuse’라고 말하는 것이다.

하지만 합성에도 오용에 따른 담점과 주의해야 할 점이 존재한다. 우선 합성은 객체 간의 관계가 수직관계가 아닌 수평 관계가 된다. 따라서 큰 시스템에서 많은 부분에 걸쳐 합성이 사용될 때 객체나 메서드명이 명확하지 않으면 코드가 가독성이 떨어지고 이해하기 어려워지게 된다. 따라서 합성을 사용할 때에는 그 용도에 따라 클래스들을 패키지로 적적하게 분리해야 하고 각각의 사용 용도가 명확하게 드러나도록 인터페이스를 잘 설계해야 한다.

디자인패턴

글 내비게이션

Previous post
Next post

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

최신 글

  • AssertJ 소개testCompile ‘org.assertj:assertj-core:3.6.2’ 2017년 9월 14일
  • 자주 사용되는 Lombok 어노테이션 2017년 9월 14일
  • 유니코드 #3 2017년 9월 14일
  • 유니코드 #2 2017년 9월 14일
  • 유니코드 #1 2017년 9월 14일

최신 댓글

    카테고리

    • 개인 자료 (1)
      • 일기 (1)
    • 주절주절 (7)
    • 프로그래밍 갤러리 (16)
    • 프로그래밍 언어 (186)
      • Java (29)
      • C/C++/VC++ (114)
      • C# (11)
      • Visual Basic (6)
      • 안드로이드 (9)
      • Objective-C (5)
      • JavaScript (4)
      • JSP/Servlet (2)
      • Python (4)
      • 어셈블러 (1)
    • 개발++ (44)
      • Book (11)
        • Joel On Software (10)
      • 프로젝트 관리 (6)
      • Maven (1)
      • 디버깅 (1)
      • DirectX (1)
      • Silverlight (1)
      • RESTful (1)
      • Hacking (1)
      • WDM (4)
      • VoIP (5)
      • 기타 (1)
    • 개발 도구 (15)
      • eclipse (14)
      • Sublime Text (1)
    • 네트워크 (7)
    • 설치 및 배포 (7)
      • InstallShield (2)
      • NSIS (4)
    • 버전 관리 (9)
      • Git (2)
      • CVS (2)
      • Subversion (5)
    • 데이터베이스 (7)
      • Oracle (3)
      • Sybase (2)
      • MS-SQL (2)
    • 단위테스트 (3)
      • JUnit (1)
      • NUnit (2)
    • 버그추적시스템 (2)
      • mantis (2)
    • 운영체제 (7)
      • Windows (5)
      • 리눅스 (2)
    • WAS (3)
      • WebLogic (3)
    • 디자인패턴 (1)
    • 디지털 이미지 프로세싱 (16)

    태그

    Abstract ActiveX AfxParseURL Automation boost devenv.exe event EventLogTraceListener Hover interface IO iTextSharp JAD jar JavaScript Joel Leave MFC Monitor msdev.com MSDN mutable PDF Properties RAW Saturation SHGetFolderPath SHGetKnownFolderPath SQLite STLTask String TextWriterTraceListener URL VI 권한 데이터소스 디컴파일러 문자열 스레드 동기화 스레드 생성 실용주의 프로그래머 자동화 테스팅 파일포맷 프리컴파일

    메타

    • 로그인
    • 엔트리 피드
    • 댓글 피드
    • WordPress.org
    ©2025 DarkKaiser의 블로그 | WordPress Theme by SuperbThemes