Search

Chapter 14. 컴퍼지트 패턴

생성일
2025/06/28 08:45
태그

컴퍼지트 패턴

컴퍼지트 패턴은 전체에 부분을 이루는 객체들을 자료구조를 통해 저장하여, 전체 클래스 코드를 바꾸지 않고도 부분에 해당하는 객체들을 추가나 삭제 할 수 있다. 부분-전체 관계를 갖는 객체들을 정의할 때 유용하다.
Composite : 복수 개의 Component를 갖도록 정의하는 전체 클래스
Component : Leaf 클래스와 전체에 해당하는 Composite 클래스의 공통 인터페이스
Leaf : 부분에 대한 구체 클래스이자 Composite의 부품
컴퍼지트 패턴을 순차 다이어그램으로 표현하면 이와 같다.

컴퓨터 부품 예제로 컴포지트 패턴 이해하기

컴퓨터 부품 예제

컴퓨터를 키보드, 본체, 모니터로 모델링하면 이와 같이 할 수 있다.
public class Body { private int price; private int power; public Body(final int price, final int power) { this.price = price; this.power = power; } public int getPrice() { return price; } public int getPower() { return power; } }
Java
복사
public class Keyboard { private int price; private int power; public Keyboard(final int price, final int power) { this.price = price; this.power = power; } public int getPrice() { return price; } public int getPower() { return power; } }
Java
복사
public class Monitor { private int price; private int power; public Monitor(final int price, final int power) { this.price = price; this.power = power; } public int getPrice() { return price; } public int getPower() { return power; } }
Java
복사
public class Computer { private Body body; private Monitor monitor; private Keyboard keyboard; public Computer(final Body body, final Monitor monitor, final Keyboard keyboard) { this.body = body; this.monitor = monitor; this.keyboard = keyboard; } public int getPrice() { int price = 0; price += body.getPrice(); price += monitor.getPrice(); price += keyboard.getPrice(); return price; } public int getPower() { int power = 0; power += body.getPower(); power += monitor.getPower(); power += keyboard.getPower(); return power; } }
Java
복사
public class Client { public static void main(String[] args) { final Body body = new Body(100, 70); final Monitor monitor = new Monitor(20, 30); final Keyboard keyboard = new Keyboard(5, 2); final Computer computer = new Computer(body, monitor, keyboard); final int power = computer.getPower(); final int price = computer.getPrice(); System.out.println("power = " + power); System.out.println("price = " + price); } }
Java
복사
이를 코드로 나타내면 위와 같다.

문제점

만약 이렇게 모델링된 컴퓨터에 Speaker라는 부품을 추가하는 경우에는
public class Computer { private Body body; private Monitor monitor; private Keyboard keyboard; private Speaker speaker; public Computer(final Body body, final Monitor monitor, final Keyboard keyboard, final Speaker speaker) { this.body = body; this.monitor = monitor; this.keyboard = keyboard; this.speaker = speaker; } public int getPrice() { int price = 0; price += body.getPrice(); price += monitor.getPrice(); price += keyboard.getPrice(); price += speaker.getPrice(); return price; } public int getPower() { int power = 0; power += body.getPower(); power += monitor.getPower(); power += keyboard.getPower(); power += speaker.getPower(); return power; } }
Java
복사
이처럼 Computer 클래스의 코드 변경이 발생하게 되어 OCP를 위반하게 된다.

해결책

이 문제를 컴포지트 패턴을 통해 해결할 수 있다.
이처럼 ComputerDevice라는 인터페이스를 두어 컴퓨터 부품들을 추상화하고, Computer 클래스 내부에 ComputerDevice 자료구조를 두어 확장 가능하도록 구현하는 것이다.
public class Body implements ComputerDevice { ... } public class Monitor implements ComputerDevice { ... } public class Keyboard implements ComputerDevice { ... }
Java
복사
public class Computer implements ComputerDevice { private List<ComputerDevice> computerDevices; public Computer(final List<ComputerDevice> computerDevices) { this.computerDevices = computerDevices; } public int getPrice() { return computerDevices.stream() .mapToInt(ComputerDevice::getPrice) .sum(); } public int getPower() { return computerDevices.stream() .mapToInt(ComputerDevice::getPower) .sum(); } }
Java
복사
public class Client { public static void main(String[] args) { final Body body = new Body(100, 70); final Monitor monitor = new Monitor(20, 30); final Keyboard keyboard = new Keyboard(5, 2); final Computer computer = new Computer(List.of(body, monitor, keyboard)); final int power = computer.getPower(); final int price = computer.getPrice(); System.out.println("power = " + power); System.out.println("price = " + price); } }
Java
복사
이렇게 설계하면 Speaker 클래스를 추가하는 경우에도,
public class Client { public static void main(String[] args) { final Body body = new Body(100, 70); final Monitor monitor = new Monitor(20, 30); final Keyboard keyboard = new Keyboard(5, 2); final Speaker speaker = new Speaker(10, 10); final Computer computer = new Computer(List.of(body, monitor, keyboard, speaker)); final int power = computer.getPower(); final int price = computer.getPrice(); System.out.println("power = " + power); System.out.println("price = " + price); } }
Java
복사
이와 같이 Computer 클래스의 변경 없이도 확장 가능해진다.