728x90
반응형
SMALL
컴포지트(Composite)패턴에 대한 정리
컴포지트(Composite)
객체를 트리 구조로 구성하여 부분과 전체를 나타내는 계층구조로 만든 것
클라이언트에서 개별 객체와 다른 객체들로 구성된 복합 객체를 똑같은 방법으로 다룰 수 있음
사용 이유
- 부분-전체 관계를 가진 객체가 있고, 그 객체들을 모두 같은 방식으로 다루고 싶을때 사용
- 객체의 구조가 복잡할 때 객체 간의 결합도를 낮추어 유연성을 높이기 위해 사용
* 부분-전체 관계 : gui에서 프레임, 패널같은 최상위 구성요소가 있고 그 안에 메뉴나 텍스트들, 버튼, 스크롤 등이 있는것
구조

- 복합 객체 : 복합객체, 잎으로 분류되고 아래와 같은 트리구조를 이룸

사용 예시

- MenuComponent : 메뉴 아이템과, 메뉴 모두에 적용되는 공용 인터페이스 역할을 하는 구성요소 인터페이스
class MenuComponent {
MenuComponent( const MenuComponent& ); // Disable copy constructor
void operator=( const MenuComponent& ); // Disable assignment operator
public:
MenuComponent();
virtual ~MenuComponent();
virtual void add( MenuComponent* menuComponent );
virtual void remove( MenuComponent* menuComponent );
virtual string getName() const;
virtual string getDescription() const;
virtual double getPrice() const;
virtual bool isVegetarian() const;
virtual void print() const;
}
- MenuItem : MenuComponent 를 상속받고, 메뉴 아이템에 쓰일법한 메소드만 오버라이드
class MenuItem : public MenuComponent {
string _name;
string _description;
bool _vegetarian;
double _price;
public:
MenuItem( const string name, const string description, bool vegetarian, double price );
string getName() const;
string getDescription() const;
double getPrice() const;
bool isVegetarian() const;
void print() const;
};
MenuItem::MenuItem( const string name, const string description, bool vegetarian, double price ) :
_name( name ), _description( description ), _vegetarian( vegetarian ), _price( price )
{
PrintMessage("MenuItem::MenuItem");
}
string MenuItem::getName() const
{
PrintMessage("MenuItem::getName");
return _name;
}
string MenuItem::getDescription() const
{
PrintMessage("MenuItem::getDescription");
return _description;
}
double MenuItem::getPrice() const
{
PrintMessage("MenuItem::getPrice");
return _price;
}
bool MenuItem::isVegetarian() const
{
PrintMessage("MenuItem::isVegetarian");
return _vegetarian;
}
- Menu : MenuComponent 를 상속받고, 메뉴에서 쓰일법한 메소드만 오버라이드
class Menu : public MenuComponent {
string _name;
string _description;
mutable vector<MenuComponent*> _menuComponents;
public:
Menu( const string name, const string description );
void add( MenuComponent* menuComponent );
void remove( MenuComponent* menuComponent );
string getName() const;
string getDescription() const;
void print() const;
};
Menu::Menu( const string name, const string description ) :_name( name ), _description( description )
{
PrintMessage("Menu::Menu");
}
void Menu::add( MenuComponent* menuComponent )
{
assert( menuComponent );
PrintMessage("Menu::add");
_menuComponents.push_back( menuComponent );
}
string Menu::getName() const
{
PrintMessage("Menu::getName");
return _name;
}
string Menu::getDescription() const
{
PrintMessage("Menu::getDescription");
return _description;
}
- 메뉴 추가 : 메뉴 객체를 만들고, 복합 객체의 add 메소드를 사용하여 최상위 메뉴인 allMenus에 각 메뉴 추가
unique_ptr< MenuComponent > pancakeHouseMenu(new Menu( "PANCAKE HOUSE MENU", "Breakfast" ) );
unique_ptr< MenuComponent > cafeMenu(new Menu( "CAFE MENU", "Dinner" ) );
unique_ptr< MenuComponent > dinerMenu(new Menu( "DINER MENU", "Lunch" ) );
unique_ptr< MenuComponent > allMenus(new Menu( "ALL MENUS", "All menus combined" ) );
allMenus->add( pancakeHouseMenu.get() );
allMenus->add( cafeMenu.get() );
allMenus->add( dinerMenu.get() );

- 메뉴 아이템 추가
pancakeHouseMenu->add( new MenuItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99) );
pancakeHouseMenu->add( new MenuItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99) );
pancakeHouseMenu->add( new MenuItem("Blueberry Pancakes", "Pancakes made with fresh blueberries, and blueberry syrup", true, 3.49) );

- 메뉴, 메뉴 아이템 추가
unique_ptr< MenuComponent > dessertMenu(new Menu( "DESSERT MENU", "Dessert of course!" ) );
dinerMenu->add( dessertMenu.get() );
dessertMenu->add( new MenuItem("Apple Pie", "Apple pie with a flakey crust, topped with vanilla icecream", true, 1.59) );
dessertMenu->add( new MenuItem("Cheesecake", "Creamy New York cheesecake, with a chocolate graham crust", true, 1.99) );

정리
- 한 클래스에서는 한 역할만 맡아야하는 단일 역할 원칙에 위배되지만, 투명성 확보
- 안정성이 떨어짐 -> 위 예시에서 메뉴 아이템에 메뉴를 넣는 작업을 할 수도 있음
- 클라이언트를 단순화시켜 사용하기 편리함
728x90
반응형
LIST
'Design Pattern' 카테고리의 다른 글
[Design Pattern] MVVM 패턴 (0) | 2023.10.03 |
---|---|
[Design Pattern] 싱글톤 패턴 (0) | 2023.08.01 |
[Design Pattern] 디자인 패턴 종류 (0) | 2023.07.03 |