ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 컴포지트 패턴 (Composite Pattern)
    공부/디자인 패턴 2020. 3. 8. 17:59

    컴포지트 패턴이란?

    객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴으로, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 하는 패턴입니다. 객체와 객체들의 집합 간의 처리 방법의 차이가 없을 경우 사용하면 됩니다. 여기서 컴포지트는 객체 또는 객체 집합을 트리 구조로 구성하는 의미입니다. 

    단일 객체와 복합 객체의 처리 방법이 다르지 않은 경우, 전체 - 부분 관계로 정의할 수 있는데 여기의 대표적인 예는 폴더-파일 구조입니다. 


    위 클래스 다이어그램을 폴더 - 파일 구조로 표현하면 아래와 같습니다.

    예시

    위 파일 구조를 아래와 같이 표현할 수 있습니다.

    // component
    interface Node {
        public String getName();
    }
    
    // leaf
    class File implements Node {
        private String name;
        @Override
        public String getName(){ 
            return name;
        }
    }
    
    // composite
    class Directory implements Node {
        private String name;
        private List<Node> children;
        @Override
        public String getName(){ 
            return name;
        }
        public void add(Node node) {
            children.add(node);
        }
    }
    
    
    // main
    public class Main {
        public static void main(String[] args) 
        {
            Directory dir = new Directory();
            dir.add(new File());
            dir.add(new File());
            Directory secDir = new Directory();
            secDir.add(new File())
            dir.add(secDir);
        }
    }

    파이썬에서..

    파이썬에서는 위 코드와 크게 다르지 않게 구현할 수 있습니다.

    import abc
    
    
    class Node(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def name(self):
            pass
    
    
    class Directory(Node):
        def __init__(self, dirname):
            self.dirname = dirname
            self._children = set()
    
        def name(self):
            for child in self._children:
                child.name()
            print(self.dirname)
    
        def add(self, component):
            self._children.add(component)
    
        def remove(self, component):
            self._children.discard(component)
    
    
    class File(Node):
        def __init__(self, filename):
            self.filename = filename
    
        def name(self):
            print(self.filename)
    
    
    def main():
        dir = Directory('dir1')
        dir.add(File('file1'))
        dir.add(File('file2'))
    
        dir2 = Directory('dir2')
        dir2.add(File('file3'))
        dir.add(dir2)
    
        dir.name()
    
    
    if __name__ == "__main__":
        main()


    댓글