출처 : https://www.inflearn.com/course/디자인-패턴
컴포지트 패턴 (Composite Pattern)
- 그룹 전체와 개별 객체를 동일하게 처리할 수 있는 패턴.
- 클라이언트 입장에서는 전체나 부분이나 모두 동일한 컴포넌트로 인식할 수 있는 계층 구조를 만든다. (Part-Whole Hierarchy)
장점
- 복잡한 트리 구조를 편리하게 사용할 수 있다.
- 다형성과 재귀를 활용할 수 있다.
- 클라이언트 코드를 변경하지 않고 새로운 엘리먼트 타입을 추가할 수 있다.
단점
- 트리를 만들어야 하기 때문에 (공통된 인터페이스를 정의해야 하기 때문에) 지나치게 일반화 해야 하는 경우도 생길 수 있다.
예시 (as-is)
public class Item {
private String name;
private int price;
public Item(String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice() {
return this.price;
}
}
public class Bag {
private List<Item> items = new ArrayList<>();
public void add(Item item) {
items.add(item);
}
public List<Item> getItems() {
return items;
}
}
public class Client {
public static void main(String[] args) {
Item doranBlade = new Item("도란 검", 450);
Item healPotion = new Item("체력 물약", 50);
Bag bag = new Bag();
bag.add(doranBlade);
bag.add(healPotion);
Client client = new Client();
client.printPrice(doranBlade);
client.printPrice(bag);
}
// 아래 printPrice가 client에 구현하는 게 맞나?
// 리프들에 공통적으로 구현되는 메서드를 interface로 분리하자
private void printPrice(Item item) {
System.out.println(item.getPrice());
}
private void printPrice(Bag bag) {
int sum = bag.getItems().stream().mapToInt(Item::getPrice).sum();
System.out.println(sum);
}
}
예시 (to-be)
// Component
public interface Component {
int getPrice();
}
// Leaf
public class Item implements Component {
private String name;
private int price;
public Item(String name, int price) {
this.name = name;
this.price = price;
}
@Override
public int getPrice() {
return this.price;
}
}
// Composite
public class Bag implements Component {
private List<Component> components = new ArrayList<>();
public void add(Component component) {
components.add(component);
}
public List<Component> getComponents() {
return components;
}
@Override
public int getPrice() {
return components.stream().mapToInt(Component::getPrice).sum();
}
}
public class Client {
public static void main(String[] args) {
Item doranBlade = new Item("도란 검", 450);
Item healPotion = new Item("체력 물약", 50);
Bag bag = new Bag();
bag.add(doranBlade);
bag.add(healPotion);
Client client = new Client();
client.printPrice(doranBlade);
client.printPrice(bag);
}
private void printPrice(Component component) {
System.out.println(component.getPrice());
}
}
활용
- 자바의 라이브러리 Swing에서의 setVisible
'Design Pattern' 카테고리의 다른 글
[Design Pattern] Factory Method Pattern (팩토리 메서드 패턴) (0) | 2022.11.13 |
---|---|
[Design Pattern] Singleton Pattern (싱글톤 패턴) (0) | 2022.11.12 |
[Design Pattern] 전략 패턴 (Strategy Pattern) (1) | 2022.10.30 |
[Design Pattern] 프록시 (Proxy) (0) | 2022.10.24 |