12. 컴포지트 패턴

AlmondGood·2022년 7월 26일
0

디자인패턴

목록 보기
13/16

컴포지트 패턴(Composite Pattern)

컴포지트 패턴 : 객체를 트리구조로 구성해서 부분-전체 계층 구조를 구현하는 패턴

이 패턴을 사용하면 전체 구조 내의 복합 객체와 개별 객체똑같은 방법으로 다룰 수 있게 됩니다.

컴퓨터 부품들이 여러 개 모여서 컴퓨터가 되듯이, 컴퓨터와 부품들의 객체를 하나로, 또 따로 접근할 수 있게 됩니다.




컴포지트 패턴 구현

컴퓨터 부품을 예로 들어보겠습니다.

컴퓨터 전체 부품의 추상 클래스입니다.
메소드는 구현하지 않고, 정의되지 않은 채로 사용하게 되면 UnsupportedOperationException 예외를 일으킵니다.

abstract class ComputerComponent {

    void add(ComputerComponent computerComponent) {
        throw new UnsupportedOperationException();
    }

	// remove는 이번에 쓰이지는 않습니다.
    void remove(ComputerComponent computerComponent) {
        throw new UnsupportedOperationException();
    }
    ComputerComponent getChild(int index) {
        throw new UnsupportedOperationException();
    }

    String getInfo() {
        throw new UnsupportedOperationException();
    }
    void print() {
        throw new UnsupportedOperationException();
    }
}

부품의 하위 정보들을 담을 클래스입니다.
예를 들면 CPU의 제작사는 Intel, Amd가 있죠.

class Component extends ComputerComponent {
    String info;

    public Component(String info) {
        this.info = info;
    }

	// 각 하위 객체의 print()
    @Override
    void print() {
        System.out.println("> " + this.info + "\n");
    }
}```

컴퓨터 클래스입니다.
부품들이 모이면 컴퓨터가 되죠.
자식을 가지는 객체를 이 클래스로 생성하면, 자식을 리스트로 쉽게 추가, 관리할 수 있습니다.

class Computer extends ComputerComponent {
    List<ComputerComponent> computerComponents = new ArrayList<>();
    String info;

    public Computer(String info) {
        this.info = info;
    }

    @Override
    void add(ComputerComponent computerComponent) {
        this.computerComponents.add(computerComponent);
    }

    @Override
    void remove(ComputerComponent computerComponent) {
        this.computerComponents.remove(computerComponent);
    }

    @Override
    ComputerComponent getChild(int index) {
        return computerComponents.get(index);
    }

    @Override
    String getInfo() {
        return this.info;
    }

    @Override
    void print() {
        System.out.println(" *" + getInfo() + "*");
        System.out.println("-------------");


        for (ComputerComponent item : computerComponents) {
            item.print();
        }
    }
}
public class CompositePattern {
    public static void main(String[] args) {
        ComputerComponent CPU = new Computer("CPU");
        ComputerComponent RAM = new Computer("RAM");
        ComputerComponent SDD = new Computer("SDD");

		// 컴퓨터 부품 전체 모음(루트 노드)
        ComputerComponent desktop = new Computer("컴퓨터 부품");
		
        desktop.add(CPU);
        desktop.add(RAM);
        desktop.add(SDD);

        CPU.add(new Component("Intel"));
        CPU.add(new Component("Amd"));

        RAM.add(new Component("Samsung"));
        RAM.add(new Component("SK Hynix"));

        desktop.print(); // -- 1
       
        desktop.getChild(0).print(); // -- 2
        desktop.getChild(0).getChild(0).print(); // -- 3        
}

'컴퓨터 부품'이라는 객체를 루트 노드로 만들고,
'컴퓨터 부품'에 'CPU', 'RAM', 'SDD' 자식 객체를 추가하고,
또 'CPU'에 자식 객체 'Intel"과 'Amd"를 추가했습니다.

1번 결과 출력


2번 결과 출력


3번 결과 출력

이처럼 객체의 전체 또는 부분을 접근할 수 있게 되었습니다.




컴포지트 패턴 장단점

장점

  • 객체들이 모두 같은 타입으로 취급되기 때문에 새로운 클래스 추가가 용이합니다.
  • 단일객체, 집합객체 구분하지 않고 코드 작성이 가능합니다.

단점

  • 설계를 일반화 시켜 객체간의 구분, 제약이 힘듭니다.
profile
Zero-Base to Solid-Base

0개의 댓글