본문 바로가기

Design Pattern

[Design pattern] 복합체 Composite


패턴

: 복합체(Composite)

 

의도

: 부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성한다. 사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴이다.

 

동기

: 그래픽 편집기나 구조도 캡쳐 시트템 같은 그래픽 응용프로그램을 살펴보면, 사용자가 간단한 그림 구성요들을 모아서 복잡한 다이어그램을 생성할 수 있게 한다. 사용자는 더 큰 그림 요소를 만글기 위해 구성요소들을 그룹으로 만들고,

이 그룹이 다 더큰 그룹을 형성하기도 한다.

이는 마이크로소프트의 파워포인트의 그룹 기능을 생각하면 이해하기 쉽다.

 

출처 : http://blog.naver.com/gamediz/20042595126

 

: 1번은 A, B, C, D라는 객체를 놓았다.

: 2번은 B객체를 늘렸다. 객체 하나에 대한 컨트롤이다.

: 3번은 A, B, C, D 그룹화 해서 한 방향으로 늘렸다.

: 4번은 B, C, D를 그룹화 하여 한 방향으로 늘리고 A는 단일객체로 남겨두었다.

 

활용성

: 부분 - 전체의 객체 계통을 표현하고 싶을 때.

: 사용자가 객체의 합성으로 생긴 복합 객체와 개개의 객체 사이의 차이를 알지 않고도, 자기 일을 할 수 있도록 만들고 싶을 때, 사용자는 복합 구조(composite structure)의 모든 객ㅊ를 똑같이 취급하게 된다.

 

구조도

 

결과

: 기본 객체와 복합 객ㅊ로 구성된 하느이 일관된 클래스 계통을 정의한다.

: 사용자 코드가 단순해 진다.

: 새로운 종류의 구성 요소를 쉽게 추가할 수 있다.

: 설계가 지나치게 범용성을 많이 가진다.

 

예제

컴퓨터는 스테레오 부품들처럼 다양한 장비들을 포함하는 객체로, 컴퓨터와 장비 객체 간의 부분 - 전체 관계가 성립한다. 본체는 드라이브와 평명 보드를 포함하고, 버스는 카드를, 캐비닛은 덮개와 버스를 포함하는 예제인데, 이런 구조는 복합체 패턴이라 할 수 있다.

 

1. Equipment 클래스로 집합 관계에서 포함되는 장비 객체들에 대한 인터페이스를 정의 한다.

class Equipment

{

public :

virtual ~Equipment();

const char* Name() { return _name; ; }

 

virtual Watt Power(); virtual Currency NetPrice(); virtual Currency Discountrice();

virtual void Add(Equipment*);

virtual void Remove(Equipment*);

virtual Iterator<Equipment*>* CreateIerator();

 

protected : Equipment(const char*);

private :

const char* _name;

};

- Equipment 클래스는 장비의 가격을 반환하는 데 필요한 연산(NetPrice(), DiscountPrice())들에 대한 인터페이스를

정의하고, 이를 상속받는 서브클래스는 인터페이스에 대한 실제 구현을 정의하여, 특정 장비에 대한 가격을 반환한다.

 

- Equipmnet 클래스는 CreateIterator()연산을 선언하여 자신이 포함하는 요소를 접근,관리하는 데 필요한 Irerator를

만들어 반환하도록 정의합니다. 기본 구현은 공집합을 순환하는 Iterator인 Null - Iterator를 반환한다.

 

2. Equipmnet의 서브 클래스에는 디스크 드라이브, 집적 회로, 스위치 등을 나타내는 말단 클래스들이 포함될 것이다.

class FloppyDist : public Equipment

{

public :

FloppyDist(const char*);

virtual ~FloppyDist();

virtual Watt Power();

virtual Currency NetPrice();

virtual Currency Discountrice();

};

3. Equipment를 동일하게 상속받으면서 무엇인가를 포함할 수 있는 복합 객체를 CompositeEquipment로 정의하였다.

class CompositeEquipment : public Equipment

{

public :

virtual ~CompositeEquipment();

 

virtual Watt Power(); virtual Currency NetPrice(); virtual Currency Discountrice();

virtual void Add(Equipment*);

virtual void Remove(Equipment*);

virtual Iterator<Equipment*>* CreateIerator();

 

protected : CompositeEquipment(const char*);

private :

List<Equipment*> _equipment;

}

 

- CompositeEquipment는 Equipment에 정의된 인터페이스에 대한 실제 구현을 제공하며, 복합 객체이므로

CompositeEquipment는 자신이 포함하는 복합 부분들을 관리하는 연산을 정의합니다. 즉, Add(), Remove()는 장비

리스트에 장비를 추가 삭제하는 연산이며, CreateIterator() 연산은 이 리스트를 순회하는 iterator를 반환한다.

4. 업무 처리 연산 중 하나인 NetPrice의 구현을 보면, CreateIterator를 사용하여 자신이 포함하는 각 구성요소를 구하고

이 구성요소 객체에 다시 NetPrice()매서드를 호출하여 각 구성요소의 값을 구한 후 이 값들을 합산하여 전ㅊ 가격을

구하고 있다.

Currency CompositeEquipment::NetPrice()

{

Iterator<Equipment*>* i = CreateIerator(); Currency total = 0;

for( i->First(); !->IsDone(); i->Next()

{

total += i->CurrentItem()->NetPrice();

}

delete i;

return total;

}

5. 이제는 컴퓨터 새시를 CompositeEquipment의 서브 클래스인 Chassis로 나타 낼 수 있다. Chassis는 자식 관련 연산을 모두 CompositeEquipment에서 물려 받습니다.

class Chassis : public CompositeEquipment

{

public :

Chassis(const char*);

virtual ~Chassis();

virtual Watt Power();

virtual Currency NetPrice();

virtual Currency Discountrice();

};

6. Cabinet과 Bus는 Chassis 클래스와 동일한 방법으로 복합 객체의 특성을 갖도록 정의한다. 컴퓨터 조립에 필요한 장치는 다 모인 셈이다.

 

Cabinet *cabinet = new Cabinet("PC Cabinet"); Chassis *chassis = new Chassis("PC Chassis");

cabinet->Add(chassis);

Bus* bus = new Bus("MCA Bus");

bus->Add(new Card("16Mbs Token Ring"));

chassis->Add(bus);

chassis->Add(new FloppyDist("3.5bin Floppy"));

cout << "The net price is " << chassis->NetPrice() << endl;

끝.-

'Design Pattern' 카테고리의 다른 글

[Design pattern] DECORATOR  (0) 2013.02.25
[Design pattern] 반복자 Iterator  (0) 2013.02.25
[Design pattern] 감시자 Observer  (0) 2013.02.25
[Design pattern] Bridge  (0) 2013.02.21
[Design pattern] Reflection  (0) 2013.02.21