컴퍼지트 패턴: 부분이 변화하더라도 기존 코드를 변경시키지 않도록 하는 패턴
기존 코드: 컴퓨터 클래스는 키보드, 본체, 모니터 클래스와 Composition 관계이다.

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;
}
}
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;
}
}
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;
}
}
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;
}
}
public class Client{
public static void main(String[] args) {
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+" 만원");
}
}
문제점: 만약 부품으로 스피커나 마우스가 추가되면 기존의 Computer 클래스를 수정해야 된다. -> OCP 위배
해결 방법: 구체적인 부품들을 일반화한 클래스를 정의하고 이를 가리키도록 설계한다.

abstract class ComputerDevice{
public abstract int getPrice();
public abstract int getPower();
}
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;
}
}
class Body extends ComputerDevice{
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;
}
}
class Monitor extends ComputerDevice{
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;
}
}
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;
}
}
public class Client{
public static void main(String[] args) {
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+" 만원");
}
}