컴퍼지트 패턴(Composite Pattern)
- 부분(part)-전체(whole)의 관계를 가지는 객체들을 정의할 때 유용
- 클라이언트는 전체와 부분을 구분하지 않고 동일한 인터페이스를 사용할 수가 있다.
컴퓨터에 추가 장치 지원하기 Example
- 소스 코드
1
2
3
4
5
6
7
8
9
public class Keyboard {
private int price;
private int power;
public Keyboard(int power, int price) {
this.power = power; this.price = price;
}
public int getPrice() { return price; }
public int getPower() { return power; }
}
1
2
3
4
5
6
7
8
9
public class Body {
private int price;
private int power;
public Body(int power, int price) {
this.power = power; this.price = price;
}
public int getPrice() { return price; }
public int getPower() { return power; }
}
1
2
3
4
5
6
7
8
9
public class Monitor {
private int price;
private int power;
public Monitor(int power, int price) {
this.power = power; this.price = price;
}
public int getPrice() { return price; }
public int getPower() { return power; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Computer {
private Body body;
private Keyboard keyboard;
private Monitor monitor;
public void addBody(Body body) { this.body = body; }
public void addKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
public void addMonitor(Monitor monitor) { this.monitor = monitor; }
public int getPrice() {
int bodyPrice = body.getPrice();
int keyboardPrice = keyboard.getPrice();
int monitorPrice = monitor.getPrice();
return bodyPrice + keyboardPrice + monitorPrice;
}
public int getPower() {
int bodyPower = body.getPower();
int keyboardPower = keyboard.getPower();
int monitorPower = monitor.getPower();
return bodyPower + keyboardPower + monitorPower;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Client {
public static void main(String[] args) {
// 컴퓨터의 부품으로서 Body, Keyboard, Monitor 객체를 생성함
Body body = new Body(100, 70);
Keyboard keyboard = new Keyboard(5, 2);
Monitor monitor = new Monitor(20, 30);
// Computer 객체를 생성하고 부품 객체들을 설정함
Computer computer = new Computer();
computer.addBody(body);
computer.addKeyboard(keyboard);
computer.addMonitor(monitor);
// 컴퓨터의 가격과 전력소비량을 구함
int computerPrice = computer.getPrice();
int computerPower = computer.getPower();
System.out.println("Computer Power: " + computerPower + " W");
System.out.println("Computer Price: " + computerPrice + " 만원");
}
}
- 실행 결과
문제점
- 만약 부품으로서 Speaker를 추가해야 한다면? 또는 Mouse를 추가한다면?
해결책
구체적인 부품들을 일반화한 클래스를 정의하고 이를 가리키도록 설계
소스 코드
1
2
3
4
public abstract class ComputerDevice {
public abstract int getPrice();
public abstract int getPower();
}
1
2
3
4
5
6
7
8
9
10
11
public class Keyboard extends ComputerDevice {
private int price;
private int power;
public Keyboard(int power, int price) {
this.power = power;
this.price = price;
}
public int getPrice() { return price; }
public int getPower() { return power; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Computer extends ComputerDevice {
// 복수 개의 ComputerDevice를 가리킴
private List<ComputerDevice> components = new ArrayList<ComputerDevice>();
// ComputerDevice를 Computer에 추가
public void addComponent(ComputerDevice component) {
components.add(component);
}
// ComputerDevice를 Computer에서 제거
public void removeComponent(ComputerDevice component) {
components.remove(component);
}
public int getPrice() {
int price = 0;
for ( ComputerDevice component: components )
price += component.getPrice();
return price;
}
public int getPower() {
int power = 0;
for ( ComputerDevice component: components )
power += component.getPower();
return power;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Client {
public static void main(String[] args) {
// 컴퓨터의 부품으로서 Body, Keyboard, Monitor 객체를 생성함
Body body = new Body(100, 70);
Keyboard keyboard = new Keyboard(5, 2);
Monitor monitor = new Monitor(20, 30);
// Computer 객체를 생성하고 부품 객체들을 설정함
Computer computer = new Computer();
computer.addComponent(body);
computer.addComponent(keyboard);
computer.addComponent(monitor);
int computerPrice = computer.getPrice();
int computerPower = computer.getPower();
System.out.println("Computer Power: " + computerPower + " W");
System.out.println("Computer Price: " + computerPrice + " 만원");
}
}
- 만약 스피커가 새로 추가된다면?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Client {
public static void main(String[] args) {
// 컴퓨터의 부품으로서 Body, Keyboard, Monitor, Speaker 객체를 생성함
Body body = new Body(100, 70);
Keyboard keyboard = new Keyboard(5, 2);
Monitor monitor = new Monitor(20, 30);
Speaker speaker = new Speaker(10, 10);
// Computer 객체를 생성하고 부품 객체들을 설정함
Computer computer = new Computer();
computer.addComponent(body);
computer.addComponent(keyboard);
computer.addComponent(monitor);
computer.addComponent(speaker);
int computerPrice = computer.getPrice();
int computerPower = computer.getPower();
System.out.println("Computer Power: " + computerPower + " W");
System.out.println("Computer Price: " + computerPrice + " 만원");
}
}
- 실행 결과
컴퍼지트 패턴의 일반적인 형태
컴퍼지트 패턴의 순차 다이어그램
컴퍼지트 패턴을 위에 적용한 클래스 다이어그램
출처
- Java객체지향 디자인패턴(한빛미디어)