항목 38 has-a 혹은 is-implemented-in-terms-of를 모형화할 때는 객체 합성을 사용하자
38.1 객체 합성
- 합성(composition)
- 어떤 타입의 객체가 다른 타입의 객체를 포함하고 있을 때, 두 타입 사이의 관계를 일컫는다.
- 계층(layering), 포함(containment), 통합(aggregation), 혹은 내장(embedding)과 동의어이다.
38.2 객체 합성의 의미
■ 38.2.1 응용 영역과 has-a
- 소프트웨어 응용 영역(application domain)
- 사람, 이동 수단 등 일상생활에서 볼 수 있는 사물을 본뜬 객체가 속한 영역을 말한다.
- 객체 합성이 응용 영역에서 일어나면 has-a 관계를 갖는다.
class Address { ... };
class PhoneNumber { ... };
class Person {
public
...
private:
std::string mName; // 사람은 이름을 가진다.
Address mAddress; // 사람은 주소를 가진다.
PhoneNumber mVoiceNumber; // 사람은 전화번호를 가진다.
PhoneNumber mFaxNumber; // 사람은 팩스번호를 가진다.
};
■ 38.2.2 구현 영역과 is-implemented-in-terms-of
- 소프트웨어 구현 영역(implementation domain)
- 응용 영역에 속하지 않는 버퍼, 뮤텍스, 탐색 트리 등 시스템 구현을 위한 객체가 속한 영역이다.
- 객체 합성이 구현 영역 사이에서 일어나면 is-implemented-in-terms-of 관계를 나타낸다.
① is-a로 잘못 구현한 Set 템플릿 클래스
- 객체로 구성된 집합을 나타내는 Set 클래스 템플릿을 is-a 관계로 만든다.
- 중복 원소가 없고 저장 공간도 적게 차지해야 하므로 표준 라이브러리 list 템플릿을 상속하기로 결정한다.
- list 객체는 중복 원소를 가질 수 있는 컨테이너고 Set 객체는 원소가 중복되면 안 된다.
- 즉, Set이 list의 일종이라는 명제는 거짓이 된다.
// set은 중복 원소를 가질 수 없지만, list는 가질 수 있으므로 is-a 관계가 어긋납니다.
template <typename T>
class Set : public std::list<T> { ... };
② is-implemented-in-terms-of로 올바르게 구현한 Set 템플릿 클래스
- 객체로 구성된 집합을 나타내는 Set 클래스 템플릿을 is-implemented-in-terms-of 관계로 만든다.
- Set 객체는 list 객체를 써서 구현되는 형태로 설계할 수 있다.
- Set의 멤버 함수는 list에서 이미 제공하는 기능과 표준 라이브러리의 다른 구성 요소로 만들 수 있다.
tempalte <typename T>
class Set {
public:
bool member(const T& item) const;
void insert(const T& item);
void remove(const T& item);
std::size_t size() const;
private:
std::list<T> rep; /* Set 데이터 내부 표현 부분입니다. */
};
NOTE
① 객체 합성(composition)의 의미는 public 상속이 가진 is-a 의미와 완전히 다르다.
② 객체 합성은 응용 영역에서 has-a, 구현 영역에서 is-implemented-in-terms-of의 의미를 갖는다.
'Object Oriented Programming(C++) > Effective C++' 카테고리의 다른 글
Effective C++ | 항목 40 다중 상속은 심사숙고해서 사용하자 (0) | 2024.08.06 |
---|---|
Effective C++ | 항목 39 private 상속은 심사숙고해서 구사하자 (0) | 2024.08.06 |
Effective C++ | 항목 37 어떤 함수에 대해서도 상속받은 디폴트 인수는 절대로 재정의하지 말자 (0) | 2024.07.26 |
Effective C++ | 항목 36 상속받은 비가상 함수를 자식 클래스에서 재정의하는 것은 절대 금물! (0) | 2023.05.21 |
Effective C++ | 항목 34 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구분하자 (0) | 2023.05.21 |
댓글