Posts [디자인패턴] 컴퍼지트 패턴(Composite Pattern)
Post
Cancel

[디자인패턴] 컴퍼지트 패턴(Composite Pattern)

컴퍼지트 패턴(Composite Pattern)

  • 부분(part)-전체(whole)의 관계를 가지는 객체들을 정의할 때 유용
  • 클라이언트는 전체와 부분을 구분하지 않고 동일한 인터페이스를 사용할 수가 있다.

컴퓨터에 추가 장치 지원하기 Example

스크린샷 2021-03-17 오후 2 02 19

  • 소스 코드
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 + " 만원");	
	}
}
  • 실행 결과
    image

문제점

  • 만약 부품으로서 Speaker를 추가해야 한다면? 또는 Mouse를 추가한다면?
    • image
    • 스크린샷 2021-03-17 오후 2 05 57
    • 스크린샷 2021-03-17 오후 2 05 48

해결책

  • 구체적인 부품들을 일반화한 클래스를 정의하고 이를 가리키도록 설계
    image

  • 소스 코드

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 + " 만원");	
	}
}
  • 만약 스피커가 새로 추가된다면?
    image
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 + " 만원");	
	}
}
  • 실행 결과
    image

컴퍼지트 패턴의 일반적인 형태

스크린샷 2021-03-17 오후 2 11 39

컴퍼지트 패턴의 순차 다이어그램

image

컴퍼지트 패턴을 위에 적용한 클래스 다이어그램

image

출처

  • Java객체지향 디자인패턴(한빛미디어)
This post is licensed under CC BY 4.0 by the author.