728x90

컴포지트 패턴(Composite Pattern)은 간단하게 말해서 단일 객체(Single Instance)든 객체들의 집합(Group of Instance) 이든 같은 방법으로 취급하는 것이다. 다시 말해, 개별적인 객체들과 집합간의 처리 방법의 차이가 없을 경우 사용하면 된다.


여기서 컴포지트의 의미는 일부 또는 그룹을 표현하는 객체들을 트리 구조(Tree Structures)로 구성한다는 뜻이다.




컴포지트 패턴을 활용은 다음과 같은 곳에서 사용할 수 있다.


파일 시스템을 간단하게 구현한다고 생각했을 때, 먼저 필요한 것은 파일이다. 그래서 파일 클래스를 만들었다.


class File { private: String name; // ... }



그리고 파일들을 가질 수 있는 디렉토리 클래스가 필요할 것이다. 


class Directory { private: String name; List<File> children; // ... public: void add(File file) { // ... } }




디렉토리 클래스는 자신의 이름과 파일들을 가질 수 있다. add() 를 이용해 파일을 추가할 수도 있을 것이다.

근데 이 구조에서 디렉토리 안에 디렉토리가 있는 것을 어떻게 표현해야 할까?




/** INode 클래스는 기본적인 파일 및 디렉토리의 근간이라고 가정합니다. 모든 파일과 디렉토리는 이름을 가지고 있을테니 이름을 반환할 getName() 메소드를 가집니다. */ class INode { public: virtual String getName() = 0; } /** File 클래스는 INode 인터페이스를 구현하면 끝입니다.

자신은 자식 요소를 가질 필요가 없기 때문이죠.

*/ class File : public INode { private: String name; // ... public: virtual String getName()    { return name; } } /** Directory 클래스는 INode 인터페이스를 구현하는 것 외에도

자식 요소를 담아둘 List가 필요합니다. */ class Directory : public INode { private:     String name;     std::list<INode> children; // ... public: virtual String getName()    { return name; } public void add(Node node) { children.add(node); } }



이제 사용을 한다면 다음과 같이 사용하게 될 것이다.



Directory dir = new Directory();
dir.add(new File()); // 디렉토리에 파일 하나를 삽입!
dir.add(new Directory()); // 디렉토리에 디렉토리를 삽입!
Directory secondDir = new Directory();
secondDir.add(dir); // 기존 루트 디렉토리를 새로 만든 디렉토리에 삽입!



간단하지만 트리 구조를 표현할 수 있는 파일 시스템을 만들었다. 이것이 바로 컴포지트 패턴을 이용한 것이다.



실제로 컴포지트 패턴의 UML은 다음과 같다.



Component : 모든 표현할 요소들의 추상적인 인터페이스를 말한다. 위의 예제 코드에서 INode 인터페이스가 이 역할을 

                  담당하고 있었다.


Leaf : Leaf 요소는 Component로 지정된 인터페이스를 구현한 것이다. 위의 예제 코드에서 File 클래스가 이 역할을 담당

        하고 있었다.


Composite : Composite 요소는 Component 요소를 자식으로 가진다. 따라서 Component 요소를 관리하기 위한 메소드들

                을 추가적으로 구현해줘야한다. 위의 예제 코드에서는 Directory 클래스가 이 역할을 담당하고 있었다.




출처 : http://jdm.kr/blog/228

728x90

+ Recent posts