Exist Technote

[Python] Composite Pattern (복합체 패턴) 본문

Design Pattern/Structural

[Python] Composite Pattern (복합체 패턴)

by_Exist 2020. 10. 6. 22:05

http://gajon.org/trees-linked-lists-common-lisp/

Composite Pattern이란?

  • 객체들의 관계가 트리 구조(단일-복합)로 구성되어 있고 단일 객체와 복합 객체를 동일하게 다루어야 할 때 사용되는 패턴.
  • 점->선->면(그리기, 지우기...), 파일->폴더(삭제, 이동...)

예제

from abc import ABC, abstractmethod


# 복합객체와 단일객체가 동일하게 갖추어야 하는 인터페이스를 정의
class Tree(ABC):

    @abstractmethod
    def render(self):
        pass


class Leaf(Tree):

    NUMBERING = 1

    def __init__(self):
        self._number = self.NUMBERING
        self.__class__.NUMBERING += 1

    def render(self, deep=0, tab_size=4):
        front_space = deep * (" " * tab_size)
        print(f"{front_space}Leaf{self._number}")


class Node(Tree):

    NUMBERING = 1

    def __init__(self):
        self._childs = []
        self._number = self.NUMBERING
        self.__class__.NUMBERING += 1

    def add(self, *childs):
        self._childs.extend(childs)

    def remove(self, child):
        self._childs.remove(child)

    def render(self, deep=0, tab_size=4):
        front_space = deep * (" " * tab_size)
        print(f"{front_space}Node{self._number}")
        for child in self._childs:
            child.render(deep+1, tab_size)


if __name__ == "__main__":

    print("\n===   Create Tree   ===")
    node1 = Node()
    node2 = Node()
    leaf1 = Leaf()
    leaf2 = Leaf()
    node2.add(leaf1, leaf2)
    node1.add(node2)
    leaf3 = Leaf()
    node1.add(leaf3)
    node3 = Node()
    node1.add(node3)
    leaf4 = Leaf()
    leaf5 = Leaf()
    node3.add(leaf4, leaf5)
    node1.render()

    print("\n===   Remove leaf3   ===")
    node1.remove(leaf3)
    node1.render()

    print("\n===   Remove node2   ===")
    node1.remove(node2)
    node1.render()

여담

  • child가 parent를 참조하면 더 효율적인 방식으로 다른 메소드를 정의할 수 있겠구나.
  • 방문자 패턴을 활용해서 leaf 또는 node 둘 중 한 종류들만 참조할 수도 있겠다.
  • 추후 노코드 매크로 프로그램을 만들게 되면, 해당 패턴을 사용할 곳이 분명 있을 거라고 생각한다.
Comments