[디자인패턴] 컴포지트 패턴(Composit Pattern)

Damsul·2023년 1월 27일
0

디자인패턴

목록 보기
14/15

객체들을 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴, 사용자가 개별 객체와 개별 객체들을 모아서 만들어진 복합 객체를 다룰 때, 모두 동일한 방식으로 다룰 수 있게 하는 패턴

출처 : 위키디피아

  • Component : 전체 클래스의 공통 행위를 정의해놓은 인터페이스
  • Leaf : 다른 객체를 포함하지 않는 가장 작은 단위의 Component 인터페이스 구현 클래스
  • Composite : Leaf와 Composite로 구성된 Component 인터페이스 구현 클래스
  • Client : Composite 인터페이스를 통해 객체 조작

예제

디렉토리에 파일을 추가한다고 가정해보자. 디렉토리에 파일을 직접 저장할 수 있지만 파일이 들어있는 디렉토리를 여러개 합쳐서 저장할 수 있다.

  • Component

[FileSystem.java]

public interface FileSystem {

    String getName();

    int getSize();

    void info();
}
  • Leaf

[File.java]

public class File implements FileSystem{
    private String name;
    private int size;

    public File(String name, int size) {
        this.name = name;
        this.size = size;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getSize() {
        return this.size;
    }

    @Override
    public void info() {
        System.out.println("file name : " + this.name + ", file size : " + this.size);
    }
}
  • Composite

[Directory.java]

public class Directory implements FileSystem {
    private List<FileSystem> child = new ArrayList<>();

    private String name;

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

    public void add(FileSystem fileSystem) {
        child.add(fileSystem);
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getSize() {
        int size = 0;

        for (FileSystem file : child) {
            size += file.getSize();
        }

        return size;
    }

    @Override
    public void info() {
        System.out.println("dir name : " + this.name);
        System.out.println("----------------------------start dir: " + this.name);
        for (FileSystem file : child) {
            file.info();
        }
        System.out.println("============================end dir: " + this.name);
        System.out.println();
    }
}
  • Client

[Client.java]

public class Client {

    public static void main(String[] args) {

        File file1 = new File("_3015", 15);
        File file2 = new File("_10798", 27);
        File file3 = new File("_1089", 53);
        Directory dir1 = new Directory("baekjoon");
        dir1.add(file1);
        dir1.add(file2);
        dir1.add(file3);

        Directory dir2 = new Directory("designPattern");
        File composite = new File("composite", 30);
        File proxy = new File("proxy", 40);
        File templateMethod = new File("templateMethod", 55);
        dir2.add(composite);
        dir2.add(proxy);
        dir2.add(templateMethod);

        Directory rootDir = new Directory("root");
        rootDir.add(dir1);
        rootDir.add(dir2);
        rootDir.add(new File("read.me", 10));

        System.out.println("rootDir size : " + rootDir.getSize());
        System.out.println("rootDir name : " + rootDir.getName());
        rootDir.info();

    }
}
  • 실행 결과

장단점

  • 장점
    • 복잡한 트리 구조의 클래스들을 편하게 관리할 수 있다.
      • 다형성과 재귀를 사용하기 때문
    • 기존의 코드를 수정하지 않고도 구조에 포함되는 새로운 클래스를 추가할 수 있다. - ex) 기본 컴퓨터 장치(모니터,마우스,키보드)에 장치 추가(스피커, 이어폰)
      • 개방 폐쇄 원칙
  • 단점
    • 기능이 너무 다른 클래스를 Component 인터페이스에 포함될 수 있도록 설계하는 것이 어려울 수 있다.
    • Component 인터페이스가 과도하게 추상화(일반화)되어 있어 다른 클래스를 포함하기 어려울 수도 있다.

  • Composite Pattern
    • 관련된 객체들을 하나의 인터페이스로 관리
  • Decorator Pattern
    • 상속 없이 동적으로 새로운 기능 추가
  • Proxy Pattern
    • 기능을 제공하는 대상에 대한 참조를 직접 관리하지 않음
profile
내 맘대로 작성하는 개발일지/ 작고 소중한 개발창고

0개의 댓글