Composite 패턴은 객체들을 트리 구조로 구성하여 개별 객체와 복합 객체(객체들의 집합)를 동일하게 취급할 수 있도록 하는 디자인 패턴인데,
객체들 간에 계층 구조를 만들어 트리로 표현하면서 개별 객체와 복합 객체를 일관성 있게 다룰 수 있게 도와줘.
#include <iostream>
#include <vector>
#include <string>
class Item
{
std::string name;
public:
Item(const std::string& name) : name(name) {}
virtual ~Item() {}
virtual int get_size() = 0;
};
class File : public Item
{
int size;
public:
File(const std::string& name, int size) : Item(name), size(size) {}
int get_size() override { return size; }
};
class Folder : public Item
{
std::vector<Item*> v;
public:
Folder(const std::string& name) : Item(name) {}
void add(Item* item) { v.push_back(item); }
int get_size() override
{
int sz = 0;
for (auto p : v)
sz += p->get_size();
return sz;
}
};
int main()
{
Folder* root = new Folder("ROOT");
Folder* fo1 = new Folder("A");
Folder* fo2 = new Folder("B");
root->add(fo1);
root->add(fo2);
File* f1 = new File("a.txt", 10);
File* f2 = new File("b.txt", 20);
fo1->add(f1);
root->add(f2);
std::cout << f2->get_size() << std::endl; // 20
std::cout << fo1->get_size() << std::endl; // 10
std::cout << root->get_size() << std::endl; // 30
}
Folder와 File이 있는데 이 둘은 각각 Size를 가지고 있다.
get_size 함수를 구현해서 size를 Return 할 껀데, 폴더는 안에 들어있는 폴더들 + 안에 들어 있는 파일의 사이즈를 Return 할꺼고, 파일이 get_size 함수를 호출하면 파일 하나의 size를 Return 하겠지.
폴더는 -> 안에 든 내용물이 무엇인지에 대해서 정리된 목록이 있어야 할 것이고
파일은 -> 자기 자신의 사이즈가 얼마인지 나타내는 값이 있어야겠지
Folder는 안에 내용물들의 pointer를 간직할 껀데, 타입을 어떻게 해야할지가 고민이 되고Folder 안에 vector를 vector<File*> 로 하면 폴더안에 들어 있는 폴더들은 담을 수가 없고
vector<Folder*>로 한다면 file 을 담을 수 없는 문제가 생기지.
그래서 이 두개를 모두 포함 할 수 있는 추상 클래스를 하나 만드는데 바로 Item 입니다.
그럼 Item*를 사용한다면 파일도 담을 수 있고 폴더도 담을 수 있어서 해결이 되는 것이죠
즉 요약하면
복합 객체(Folder)는 개별 객체 뿐만 아니라 자기 자신 또한 보관 가능해야한다. -> 공통의 기반 클래스가 필요
'Programming > c++ Design Pattern' 카테고리의 다른 글
[C++ Design Pattern] Adapter (0) | 2023.11.30 |
---|---|
[C++ Design Pattern] Decorator (0) | 2023.11.29 |
[C++ Design Pattern] Strategy Pattern (0) | 2023.11.29 |
[c++ Design Pattern] Template Method (0) | 2023.11.29 |
[C++] OCP Code 예제 (1) | 2023.11.29 |