Composite
Composite Pattern
사용 목적
여러 개의 객체들로 구성된 복합 객체(Group instance)와 단일 객체(Single instance)를 클라이언트에서 구별 없이 다루기 위해.
-
전체 - 부분의 관계(Ex. Directory-File)를 갖는 객체들 사이의 관계를 정의할때 유용하다.
-
또한, 클라이언트는 전체와 부분을 구분하지 않고 동일한 인터페이스를 사용할 수 있다.
UML Diagram
Component
- 구체적인 부분
- 즉, Leaf 클래스와 전체에 해당하는 Composite 클래스에 공통 인터페이스를 정의.
Leaf
- 구체적인 부분 클래스
- Composite 객체의 부품으로 설정한다.
Composite
- 전체 클래스
- 복수 개의 Component를 갖도록 정의
- 그러므로, 복수 개의 Leaf, 심지어 복수 개의 Composite 객체를 부분으로 가질 수 있다.
예제
// Component 클래스 - 서브 클래스들에게 동일한 목적의 기능을 강제화 한다.
public abstract class ComputerDevice {
public abstract int getPrice();
public abstract int getPower();
}
// Leaf 클래스 - 부모(Component) 클래스에게 동일한 기능을 물려받은 단일 객체
public class Keyboard {
//
private int price;
private int power;
//
private String kind;
private int keyCount;
public Keyboard(int power, int price) {
this.power = power;
this.price = price;
}
public int getPrice() { return price; }
public int getPower() { return power; }
}
public class Body { 동일한 구조 }
public class Monitor { 동일한 구조 }
public class Speaker { 동일한 구조 }
// 복수 개의 Component를 가질 수 있고, 자신 또한 Component 자식인 Composite 클래스
public class Computer implements ComputerDevice {
// 복수 개의 Leaf 객체를 가리킴
private List<ComputerDevice> components = new ArrayList<ComputerDevice>();
// Leaf 객체를 Composite 클래스에 추가
public void addComponent(ComputerDevice component){
components.add(component);
}
// Leaf 객체를 Composite 클래스에서 제거
public void removeComponent(ComputerDevice component){
components.remove(component);
}
// 전체 가격을 포함하는 각 부품의 가격을 합산
@Override
public int getPrice() {
int price = 0;
for(ComputerDevice component : components){
price += component.getPrice();
}
return price;
}
// 전체 소비 전력량을 포함하는 각 부품의 소비 전력량을 합산
@Override
public int getPower() {
int power = 0;
for(ComputerDevice component : components){
power += component.getPower();
}
return power;
}
}
public class Client {
public static void main(String[] args) {
// 컴퓨터의 부품으로 Keyboard, Body, Monitor 객체를 생성
Keyboard keyboard = new Keyboard(5, 2);
Body body = new Body(100, 70);
Monitor monitor = new Monitor(20, 30);
Speaker Speaker = new Speaker(15, 25);
// Computer 객체를 생성하고 addComponent()를 통해 부품 객체들을 설정
Computer computer = new Computer();
computer.addComponent(keyboard);
computer.addComponent(body);
computer.addComponent(monitor);
computer.addComponent(Speaker);
Computer computer2 = new Computer();
computer2.addComponent(computer);
computer2.addComponent(body);
computer2.addComponent(monitor);
computer2.addComponent(Speaker);
Computer computer3 = new Computer();
computer3.addComponent(computer2);
computer3.addComponent(keyboard);
computer3.addComponent(monitor);
computer3.addComponent(Speaker);
Computer sumComputer = new Computer();
sumComputer.addComponent(computer3);
// 컴퓨터의 가격과 전력 소비량을 구함
System.out.println("컴퓨터의 가격은 : " + sumComputer.getPrice() + "만원");
System.out.println("컴퓨터의 소비 전력은 : " + sumComputer.getPower() + "W");
}
}
참고
- https://gmlwjd9405.github.io/2018/08/10/composite-pattern.html
- https://effectiveprogramming.tistory.com/entry/Composite-%ED%8C%A8%ED%84%B4?category=660013
- https://keichee.tistory.com/184?category=834910
- Head First Design Pattern