본문 바로가기

Pattern/GOF

구조패턴 - 컴포짓패턴

반응형

1. 컴포짓패턴이란?

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

 

2. 언제 사용하는지?

위 내용에 나와 있듯이 컴포지트 패턴은 클라이언트가 복합 객체나 단일 객체를 동일하게 취급하는 것을 목적으로 한다.

기본적으로 트리 구조로 작성되며 복합 객체와 단일 객체의 처리 방법이 다르지 않을 경우 전체 - 부분 관계로 정의하여 사용한다.

트리 구조의 가장 대표적인 예로 파일과 디렉토리 관계를 예로 들 수 있다.

 

3. 샘플 코드

 

Component

// Component 역할
public interface Component
{
    public int getSize();
}

공통적으로 사용하고자 하는 메서드를 인터페이스로 정의.

 

File

// Leaf 역할
public class File implements Component
{
    private String mName;
    private int mSize;

    public File(String mName, int mSize) {
        this.mName = mName;
        this.mSize = mSize;
    }

    @Override
    public int getSize() {
        return mSize;
    }
}

전체 - 부분 관계중 부분에 해당하는 구체화 클래스.

컴포넌트를 상속한다.

 

Directory

// Composite 역할
public class Directory implements Component
{
    private String mName;

    private List<Component> mComponent = new ArrayList<>();

    public Directory(String mName) {
        this.mName = mName;
    }

    public void add(Component component)
    {
        this.mComponent.add(component);
    }

    @Override
    public int getSize() {
        return mComponent.stream().mapToInt(Component::getSize).sum();
    }
}

전체 - 부분 관계중 전체에 해당하는 복합 클래스.

File 객체와 같이 Component를 상속 받는다.

주의할 점은 컴포넌트를 정의할 때 구체화 객체를 사용하면 안된다.

private List<File> mComponent = new ArrayList<>(); ( X )

private List<Component> mComponent = new ArrayList<>(); ( O )

 

 

Client

public class Client
{
    public static void main(String[] args) {

        Directory defaultInstallDir = new Directory("Download");
        Directory ideDir = new Directory("IDE");
        File intelliJ = new File("IntelliJ_Install_Manager.exe", 1024);
        File sudden = new File("SuddenActtack", 4096);

        defaultInstallDir.add(sudden);
        ideDir.add(intelliJ);
        defaultInstallDir.add(ideDir);

        Client client = new Client();

        client.printSize(intelliJ);
        client.printSize(sudden);
        client.printSize(ideDir);
        client.printSize(defaultInstallDir);
    }

    private void printSize(Component component)
    {
        System.out.println(component.getSize());
    }
}

Client 클래스에서 단일 메서드를 통해 파일, 디렉토리 클래스의 사이즈를 확인할 수 있다.

File과 Directory 클래스를 추상화하지 않았다면

printSize(Directory d)

printSize(FIe f)

와 같이 구체화 클래스마다 메서드를 정의해주어야 했을 것이다.

 

4. 장단점

  1. 장점
    • 공통된 메서드를 사용함으로서 메서드의 개수를 줄일 수 있다.
    • 개방 폐쇄 원칙을 지킬 수 있다. (새로운 Leaf를 추가하여도 클라이언트의 printSize 코드가 변경되지 않는다.)
  2. 단점
    • Leaf와 Composite의 공통된 오퍼레이션을 사용해야 하기 때문에 사용에 어려움이 있을 수 있다.
반응형

'Pattern > GOF' 카테고리의 다른 글

행위패턴 - 책임 연쇄 패턴  (0) 2022.05.31
구조패턴 - 프록시  (0) 2022.05.26
구조패턴 - 데코레이션 패턴  (0) 2022.05.24
생성패턴 - 팩토리메서드  (0) 2022.05.11
생성패턴- 싱글톤  (0) 2022.05.09