Post List

2015년 1월 4일 일요일

has-a(..는...를 가짐) 혹은 is-implemented-in-terms-of(..는..를 써서 구현됨) 를 모형화할 때는 객체 합성을 사용하자.

합성(composition) 이란 어떤 타입의 객체들이 그와 다른 타입의 객체들을 포함하고 있는 경우의 관계를 말한다. 레이어링(layering), 포함(containment), 통합(aggregation), 내장(embedding) 으로도 불린다.

 public 상속의 의미는 is..a(..는..의 일종이다) 이다.
 합성의 의미는 has-a(..는...를 가짐) 라는 의미와 is-implemented-in-terms-of(..는..를 써서 구현됨) 의 두가지 의미를 가진다.
 이유는 소프트웨어 개발에는 두 가지 영역(domain)이 있기 때문이다.

 첫째, 응용 영역(application domain) : 일상생활에서의 사물 등과 같은 의미가 있는 객체
 둘째, 구현 영역(implementation domain) : 응용 영역에 속하지 않는 나머지, 버퍼, 뮤텍스, 탐색트리 등 순수하게 시스템 구현만을 위한 인공물

 응용 영역은 has-a 관계이다.

간단한 예를 들면 Person 이라는 Class의 멤버변수로 Address 타입이라던지 PhoneNumber 타입을 가지는 경우와 같은 것이다.

 구현 영역은 is-implemented-in-terms-of 관계이다.

 예를 들어서 list<T> 를 이용해서 set<T> 를 구현하는 경우를 생각해보자. 만약 set<T> 가 list<T>를 상속받으면 어떻게 될까 ? public 상속은 is-a 관계이기 때문에 list<T>에서 참인 것은 모두 set<T>에서도 참이어야 한다. list<T>는 중복 데이터를 가질수 있지만 set<T>은 중복 데이터를 가질 수 없기 때문에 상속으로의 구현은 안된다.


template<class T>
class set {
public:
  bool member(const T& item) const {
    return std::find(rep.begin(), rep.end(), item) != rep.end();
  }
  void insert(const T& item) {
    if (!member(item)) rep.push_back(item);
  }
  void remove(const T& item) {
    typename std::list<T>::iterator it = std::find(rep.begin(), rep.end(), item);
  if (it != rep.end()) rep.erase(it);
  }
  std::size_t size() const { return rep.size(); }
private:
  std::list<T> rep;
};



* 객체 합성(composition)의 의미는 public 상속이 가진 의미와 완전히 다릅니다.

* 응용 영역에서 객체 합성의 의미는 has-a(..는 ..를 가짐)입니다. 구현 영역에서는 is-implemented-in-terms-of(..는 ..를 써서 구현됨)의 의미를 갖습니다.



댓글 없음:

댓글 쓰기