[디자인패턴] 복합체 패턴 (Composite Pattern)

koline·2023년 9월 4일
0

디자인패턴

목록 보기
9/24

복합체 패턴 (Composite Pattern)


객체들의 관계를 트리구조로 구성하여 부분-전체 계층을 표현하는 패턴으로 사용자가 단일 객체(Leaf)와 복합 객체(Composite) 모두 동일하게 다루도록 하는 패턴이다.

즉, 복합 객체 그룹(전체)과 단일 객체를 동일하게 취급하거나 다룰 수 있게 해주는 방식으로, 재귀적 특성을 띄게 된다.

쉽게 설명하자면 윈도우나 리눅스의 파일 시스템 구조와 유사한 형태를 띄고있는데, root 디렉토리 안에 또 다른 디렉토리(Composite)가 있을수도, 파일(Leaf)이 있을 수도 있다.

복합체 패턴은 여기서 디렉토리와 파일을 동일하게 다룸으로써 구현을 단순화 시키는 것을 목적으로 한다. 이러한 구조에서 한 디렉토리에서 서브 디렉토리로 이동하게 되면 해당 디렉토리에는 파일이 있을 수도, 또 다른 서브 디렉토리가 있을 수도 있는데, 이런 복잡한 계층 구조에서 복합 객체를 재귀 함수를 이용해 하위 객체가 다루도록 위임한다. 그러면 복합 객체와 단일 객체를 대상으로 똑같은 작업을 적용할 수 있어 단일/복합 객체를 구분할 필요가 거의 없어진다.




구조


  1. Component : Leaf와 Compsite 를 묶는 공통적인 상위 인터페이스
  2. Composite : 복합 객체로서, Leaf 역할이나 Composite 역할을 넣어 관리하는 역할을 한다.
    Component 구현체들을 내부 리스트로 관리한다
    add 와 remove 메소드는 내부 리스트에 단일 / 복합 객체를 저장
    Component 인터페이스의 구현 메서드인 operation은 복합 객체에서 호출되면 재귀 하여, 추가 단일 객체를 저장한 하위 복합 객체를 순회하게 된다.
    Leaf: 단일 객체로서, 단순하게 내용물을 표시하는 역할을 한다.
    Component 인터페이스의 구현 메서드인 operation은 단일 객체에서 호출되면 적절한 값만 반환한다.
  3. Client : 클라이언트는 Component를 참조하여 단일 / 복합 객체를 하나의 객체로서 다룬다.

복합체 패턴의 핵심은 Composite 와 Leaf가 동시에 구현하는 operation() 인터페이스 추상 메서드를 정의하고, Composite 객체의 operation() 메서드는 자기 자신을 호출하는 재귀 형태로 구현하는 것이다. 왜냐하면 폴더 안에 폴더를 넣고, 그 안에 또 폴더를 넣고 파일을 넣는 트리 구조를 생각해보면, 재귀적으로 반복되는 형식이 나타나기 때문이다. 그래서 단일체와 복합체를 동일한 개체로 취급하여 처리하기 위해 재귀 함수 원리를 이용한다.



구현


// Component.java
public interface Component {
    void operation();
}

// Leaf.java
public class Leaf implements Component {
    @Override
    public void operation() {
        System.out.println("[Leaf] " + this + " has been called");
    }
}

// Composite.java
public class Composite implements Component {
    private List<Component> components = new ArrayList<>();

    public void add(Component c) {
        components.add(c);
    }

    public void remove(Component c) {
        components.remove(c);
    }

    @Override
    public void operation() {
        System.out.println("[Composite] " + this + " has been called");

        for (Component c : components) {
            c.operation();
        }
    }

    public Component getChild(int no) {
        return components.get(no);
    }

    public List<Component> getChildren() {
        return components;
    }
}

위와 같이 Component를 interface로 구현하여 operation 메서드를 추상 메서드로 선언해준다. 그리고 Leaf와 Composite에서 각각 Leaf는 하위 객체가 없으므로 본인 호출, Composite는 본인 호출 후 하위 객체(Component)를 다시 재귀적으로 호출하도록 구현해준다.

// Client.java
public class Client {
    public static void main(String[] args) {
        Composite c1 = new Composite();
        Leaf l1 = new Leaf();

        System.out.println("------- execution 1 -------");
        c1.operation();
        l1.operation();

        Composite c2 = new Composite();
        Leaf l2 = new Leaf();
        Leaf l3 = new Leaf();
        Leaf l4 = new Leaf();
        
        c1.add(l1);
        c1.add(c2);
        c2.add(l2);
        c2.add(l3);
        c2.add(l4);

        System.out.println("------- execution 2 -------");
        c1.operation();
    }
}

// 실행 결과
------- execution 1 -------
[Composite] Composite@15db9742 has been called
[Leaf] Leaf@6d06d69c has been called
------- execution 2 -------
[Composite] Composite@15db9742 has been called
[Leaf] Leaf@6d06d69c has been called
[Composite] Composite@7852e922 has been called
[Leaf] Leaf@4e25154f has been called
[Leaf] Leaf@70dea4e has been called
[Leaf] Leaf@5c647e05 has been called




목적

  1. 데이터를 다룰때 계층적 트리 표현을 다루어야 할때
  2. 복잡하고 난해한 단일 / 복합 객체 관계를 간편히 단순화하여 균일하게 처리하고 싶을때

장점

  1. 단일체와 복합체를 동일하게 여기기 때문에 묶어서 연산하거나 관리할 때 편리하다.
  2. 다형성 재귀를 통해 복잡한 트리 구조를 보다 편리하게 구성 할 수 있다.
  3. 수평적, 수직적 모든 방향으로 객체를 확장할 수 있다.
  4. 새로운 Leaf 클래스를 추가하더라도 클라이언트는 추상화된 인터페이스 만을 바라보기 때문에 개방 폐쇄 원칙(OCP)Visit Website을 준수 한다. (단일 부분의 확장이 용이)

단점

  1. 재귀 호출 특징 상 트리의 깊이(depth)가 깊어질 수록 디버깅에 어려움이 생긴다.
  2. 설계가 지나치게 범용성을 갖기 때문에 새로운 요소를 추가할 때 복합 객체에서 구성 요소에 제약을 갖기 힘들다.
  3. 예를들어, 계층형 구조에서 leaf 객체와 composite 객체들을 모두 동일한 인터페이스로 다루어야하는데, 이 공통 인터페이스 설계가 까다로울 수 있다.
    3-1. 복합 객체가 가지는 부분 객체의 종류를 제한할 필요가 있을 때
    3-2. 수평적 방향으로만 확장이 가능하도록 Leaf를 제한하는 Composite를 만들때



참고


[디자인패턴] 디자인패턴이란? - 생성패턴, 구조패턴, 행위패턴

복합체(Composite) 패턴 - 완벽 마스터하기

[디자인 패턴] 복합체 패턴 (Composite pattern)

profile
개발공부를해보자

0개의 댓글