설명
여러 객체를 가진 복합 객체와 단일 객체를 구분없이 다루고자 할 때 사용.
기본 객체와 복합 객체가 동일한 인터페이스를 상속받게 하여 이를 가능하게 함.
때문에 새로운 요소를 기존 프로그램 수정 없이 가능하게 함.
문제는 설계가 너무 범용성이 커서 복합 객체에 제약을 넣는게 힘들어짐.
여기에 관련된 이슈는 크게 두가지가 있는데
하나는 Component 에 Leaf 에게 필요없는 메소드도 있어서 나쁜 상속이 아니냐는 것이고
다른하나는 나쁜 상속을 막기위해 Composite 에 비중을 두면 모든 Component 의 통일성이 약화된다는 점. 그러면 Composite 패턴을 쓰는 목적을 읽게 되는 것.
예제 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // Leaf Node Interface class Equipment { protected: typedef std::list<Equipment*>::iterator iter_equipment; typedef float Currency; public: virtual ~Equipment() = default; const char* Name() { return _name; } virtual Currency NetPrice() = 0; protected: Equipment(const char* c) : _name(c) {} private: const char* _name; }; // LeafNode 구현 class FloppyDisk : public Equipment { public: FloppyDisk(const char* c) : Equipment(c) {} virtual ~FloppyDisk() = default; virtual Currency NetPrice() { return m_price; } private: Currency m_price = 10; }; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // Composite Interface class CompositeEquipment : public Equipment { public: virtual ~CompositeEquipment() = default; virtual Currency NetPrice() { Currency total = 0; for (auto equipment : _equipments) total += equipment->NetPrice(); return total; } protected: CompositeEquipment(const char* c) : Equipment(c) {} private: std::list<Equipment*> _equipments; }; // Composite 구현 class Chassis : public CompositeEquipment { public: Chassis(const char* c) : CompositeEquipment(c) {} virtual ~Chassis() = default; virtual Currency NetPrice() { return CompositeEquipment::NetPrice() + m_price; } private: Currency m_price = 5; }; | cs |
위에선 Tree 가 Composite, Leaf 두개 밖에 없는 간단한 경우임.
Equiment 인 FloppyDisk 와 CompositeEquipment 인 Chassis 두가지만 있음.
Chassis 가 FloppyDisk 로 구성되어 있다고 하면, Chassis 에 가격을 묻는 것과, FloppyDisk 의 가격을 묻는 것은 같은 메소드로 해결이 됨.
자세한 구현은 몰라도 되는 것임.
자식이 부모의 주소를 알고 있게 하는 것도 좋음.
CompositeEuipment 의 CompositeEuipment 도 가능은 함.
추가 설명
Decorate 패턴, Visitor 패턴과 함께 사용되기도 함.
댓글 없음:
댓글 쓰기