컴퍼지트 패턴: 부분이 변화하더라도 기존 코드를 변경시키지 않도록 하는 패턴
기존 코드: 컴퓨터 클래스는 키보드, 본체, 모니터 클래스와 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+" 만원"); } }