JUINTINATION
컴퍼지트(Composite) 패턴 본문
반응형
컴퍼지트 패턴이란?
부분-전체의 관계를 갖는 객체들 사이의 관계를 정의하여 클라이언트가 전체와 부분을 구분하지 않고 동일한 인터페이스를 사용할 수 있게 만드는 패턴이다.
다음과 같이 컴퓨터를 모델링했다고 하자.
컴퓨터는 다음과 같이 키보드(Keyboard 클래스), 본체(Body 클래스), 그리고 모니터(Monitor) 클래스로 이루어져있다.
class Keyboard {
private int price;
private int power;
public Keyboard(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Body {
private int price;
private int power;
public Body(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Monitor {
private int price;
private int power;
public Monitor(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Computer {
private Keyboard keyboard;
private Body body;
private Monitor monitor;
public void addKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
public void addBody(Body body) {
this.body = body;
}
public void addMonitor(Monitor monitor) {
this.monitor = monitor;
}
public int getPrice() {
return keyboard.getPrice() + body.getPrice() + monitor.getPrice();
}
public int getPower() {
return keyboard.getPower() + body.getPower() + monitor.getPower();
}
}
- 위 코드의 문제점
- 키보드, 본체, 모니터 이외에 스피커 등 다른 부품이 추가되면 기존의 Computer 클래스 코드를 수정해야 한다.
- 유지 보수의 어려움
- OCP 위반
- 키보드, 본체, 모니터 이외에 스피커 등 다른 부품이 추가되면 기존의 Computer 클래스 코드를 수정해야 한다.
위의 문제를 해결하기 위해 구체적인 부품들을 일반화한 클래스를 정의하고 이를 Computer 클래스가 가리키게 해보자.
import java.util.List;
import java.util.ArrayList;
abstract class ComputerDevice {
public abstract int getPrice();
public abstract int getPower();
}
class Keyboard extends ComputerDevice {
private int price;
private int power;
public Keyboard(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Body extends ComputerDevice {
private int price;
private int power;
public Body(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Monitor extends ComputerDevice {
private int price;
private int power;
public Monitor(int price, int power) {
this.price = price;
this.power = power;
}
public int getPrice() {
return price;
}
public int getPower() {
return power;
}
}
class Computer extends ComputerDevice {
private List<ComputerDevice> components = new ArrayList<>();
public void addComponent(ComputerDevice component) {
components.add(component);
}
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;
}
}
이렇게 되면 Speaker 클래스를 비롯한 다른 부품의 클래스가 생겨도 기존 코드를 수정하지 않고 사용할 수 있다.
추가적으로 이 글에 있는 일반화의 위임 부분을 보면 더 이해하기 쉬울 것 같다.
컴퍼지트 패턴 컬레보레이션
Component : 구체적인 부분, 즉 Leaf 클래스와 전체에 해당하는 Composite 클래스에 공통 인터페이스를 정의한 추상 클래스
Leaf : 구체적인 부분 클래스, Composite 객체의 부품으로 걸정한다.
Composite : 전체 클래스, 여러 개의 Component를 갖도록 정의한다. 즉, 여러 개의 Leaf 객체 및 Composite 객체를 부분으로 가질 수 있다.
728x90
'JAVA객체지향디자인패턴' 카테고리의 다른 글
추상 팩토리(Abstract Factory) 패턴 (0) | 2023.07.16 |
---|---|
팩토리 메서드(Factory Method) 패턴 (1) | 2023.07.16 |
템플릿 메서드(Template Method) 패턴 (0) | 2023.07.16 |
데커레이터(Decorator) 패턴 (0) | 2023.07.09 |
옵서버(Observer) 패턴 (0) | 2023.07.06 |
Comments