Composite Pattern
컴포지트 패턴이란 부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성한다. 사용자로 하여금 개별 객체와 복함 객체를 모두 동일하게 다룰 수 있도록 하는 패턴이다.
활용성
- 부분-전체의 객체 계통을 표현하고 싶을 때
- 사용자가 객체의 합성으로 생긴 복합 객체와 개개의 객체 사이의 차이를 알지 않고도 자기 일을 할 수 있도록 만들고 싶을 때
컴포지트 패턴 사용에 따른 결과
기본 객체와 복합 객체로 구성된 하나의 일관된 클래스 계통 정의
기본 객체는 복합 객체 내에 속해있을 수 있다. 그 복합 객체 또한 어느 복합 객체의 하위에 있을 수 있다. 그러나 사용자는 일반화된 상위 개념의 객체를 조작하는 방식으로 기본 객체와 복합 객체를 구분하지 않고 일관되게 조작할 수 있다.
코드 단순화
사용자 코드는 복합 구조이나 단일 객체와 동일하게 다루는 코드로 작성되기 때문에 코드가 단순해진다.
새로운 종류의 구성요소 쉽게 추가
새롭게 정의된 Composite나 Leaf의 서브 클래스들은 기존에 존재하는 구조들과 독립적으로 동작이 가능하다.
설계의 지나친 범용성
때론 Composite가 하나의 구성요소만 가졌어야만 하는 때도 있다. 이럴 때는 Composite 클래스만으로 제약을 가하기 힘들다.
컴포지트
구조
컴포지트의 구조는 다음과 같다.
C++ 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| auto* compositeRoot = new GraphicComposite("compositeRoot"); auto* compositeChild1 = new GraphicComposite("compositeChild1"); auto* compositeChild2 = new GraphicComposite("compositeChild2");
auto* graphicCircle1 = new GraphicCircle("graphicCircle1"); auto* graphicCircle2 = new GraphicCircle("graphicCircle2");
auto* graphicSquare1 = new GraphicSquare("graphicSquare1"); auto* graphicSquare2 = new GraphicSquare("graphicSquare2");
compositeChild1->add(graphicCircle1); compositeChild1->add(graphicCircle2);
compositeChild2->add(graphicSquare1); compositeChild2->add(graphicSquare2);
compositeRoot->add(compositeChild1); compositeRoot->add(compositeChild2);
compositeRoot->show();
|
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| class Graphic { public: virtual ~Graphic() {}; virtual void show() = 0; };
class GraphicCircle : public Graphic { std::string name; public: GraphicCircle(std::string name) { this->name = name; }
~GraphicCircle() { std::cout<<name<<" destructor"<<std::endl; }
void show() override { std::cout<<name<<std::endl; } };
class GraphicSquare : public Graphic { std::string name; public: GraphicSquare(std::string name) { this->name = name; }
~GraphicSquare() { std::cout<<name<<" destructor"<<std::endl; }
void show() override { std::cout<<name<<std::endl; } };
class GraphicComposite : public Graphic { std::string name; std::vector<Graphic*> graphicVector; public: GraphicComposite(std::string name) { this->name = name; }
~GraphicComposite() { std::cout<<name<<" destructor"<<std::endl; }
void show() override { std::cout<<name<<std::endl; for(Graphic* graphic : graphicVector) graphic->show(); }
void add(Graphic* graphic) { graphicVector.emplace_back(graphic); }
std::vector<Graphic*> remove() { return graphicVector; } };
|
java 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Client { public static void main(String[] args) { GraphicComposite rootComposite = new GraphicComposite("rootComposite"); GraphicComposite child1Composite = new GraphicComposite("child1Composite"); GraphicComposite child2Composite = new GraphicComposite("child2Composite");
Graphic graphicCircle1 = new Circle("graphicCircle1"); Graphic graphicCircle2 = new Circle("graphicCircle2");
Graphic graphicSquare1 = new Square("graphicSquare1"); Graphic graphicSquare2 = new Square("graphicSquare2");
rootComposite.add(child1Composite); rootComposite.add(child2Composite);
child1Composite.add(graphicCircle1); child1Composite.add(graphicCircle2);
child2Composite.add(graphicSquare1); child2Composite.add(graphicSquare2);
rootComposite.show(); } }
|
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public interface Graphic { void show(); }
public class Circle implements Graphic{ private String name;
public Circle(String name) { this.name = name; }
@Override public void show() { System.out.println("This Leaf is " + name); } }
public class Square implements Graphic{ private String name;
public Square(String name) { this.name = name; }
@Override public void show() { System.out.println("This Leaf is " + name); } }
public class GraphicComposite implements Graphic{ private List<Graphic> graphicList; private String name;
public GraphicComposite(String name) { this.name = name; graphicList = new ArrayList<>(); }
@Override public void show() { System.out.println("This Composite is " + name); for(Graphic graphic : graphicList) graphic.show(); }
public void add(Graphic graphic) { graphicList.add(graphic); }
public List<Graphic> remove() { return graphicList; } }
|