• 객체들의 관계를 트리구조로 구성하여 부분-전체 계층을 표현하는 패턴
  • 클라이언트가 단일객체, 복합객체 구분 없이 동일하게 다루는 것이 가능하게 해준다

용어

image

  • Component : 모든 Component의 추상화 인터페이스
  • Leaf : 구체적인 부분 클래스
  • Composite : 전체 클래스
    • Component 리스트로 가지고 있음

구현

  • Component
public abstract class ComputerParts {
  public abstract int getPrice();
  public abstract int getPower();
}
  • Leaf
    • Component 인터페이스를 구현한 구체 클래스
public class Keyboard implements ComputerParts {
  private int price;
  private int power;

  public Keyboard(int power, int price) {
    this.power = power;
    this.price = price;
  }
  @Override
  public int getPrice() { 
    return price; 
  }
  @Override
  public int getPower() { 
    return power; 
  }
}

public class Monitor implements ComputerParts {
  private int price;
  private int power;

  public Monitor(int power, int price) {
    this.power = power;
    this.price = price;
  }
  @Override
  public int getPrice() { 
    return price; 
  }
  @Override
  public int getPower() { 
    return power; 
  }
}

public class Mouse implements ComputerParts {
  private int price;
  private int power;

  public Mouse(int power, int price) {
    this.power = power;
    this.price = price;
  }
  @Override
  public int getPrice() { 
    return price; 
  }
  @Override
  public int getPower() { 
    return power; 
  }
}
  • Composite
    • Component 인터페이스 구현
    • 필드로 Component 리스트를 갖는다
public class Computer extends ComputerParts {

  private List<ComputerParts> components = new ArrayList<ComputerParts>();

  public addComponent(ComputerParts component) { 
    components.add(component); 
  }
  public removeComponent(ComputerParts component) { 
    components.remove(component); 
  }

  @Override
  public int getPrice() {
    int price = 0;
    for(ComputerParts component : components) {
      price += component.getPrice();
    }
    return price;
  }

  @Override
  public int getPower() {
    int power = 0;
    for(ComputerParts component : components) {
      price += component.getPower();
    }
    return power;
  }
}
  • Client
public class Main {
    public static void main(String[] args) {
        Keyboard keyboard = new Keyboard(10, 3);
        Monitor monitor = new Monitor(100, 70);
        Mouse mouse = new Mouse(5, 2);

        Computer computer = new Computer();
        computer.addComponent(keyboard);
        computer.addComponent(monitor);
        computer.addComponent(mouse);

        int totalPrice = computer.getPrice();
        int totalPower = computer.getPower();
    }
}

장점

  1. 클라이언트 코드를 변경하지 않고 새로운 객체를 추가할 수 있다 [OCP]
  2. 복잡한 트리 구조를 편리하게 사용할 수 있다

단점

  1. 단일 책임의 원칙이 깨진다
  2. 트리구조를 만들기 위해 복잡해 질 수 있다