Search

Chapter 10. 데커레이터 패턴

생성일
2025/06/15 02:07
태그

데커레이터 패턴

데커레이터 패턴은 기본 기능에 새로운 기능 혹은 다양한 기능을 추가해야하는 상황이 많이 발생하는 경우, 기본 기능을 상속받는 Decorator 클래스를 두고 Decorator 클래스를 조합함으로 추가 기능의 조합을 설계하는 방식이다.
Component : 기본 기능을 정의
ConcreteComponent : 기본 기능을 구현
Decorator : 추가 기능을 제공할 수 있는 추상클래스
ConcreteDecorator : 추가 기능을 구현
데커레이터 패턴을 순차 다이어그램으로 표현하면 위와 같다.

도로 표시 방법 조합하기

네비게이션에 도로를 표시하고, 추가적으로 도로의 차선을 표시하는 기능을 선택할 수 있다고 가정해보자.
public class RoadDisplay { public void draw() { System.out.println("기본 도로 표시"); } }
Java
복사
public class RoadDisplayWithLane extends RoadDisplay { @Override public void draw() { super.draw(); System.out.println("도로 차선 표시"); } }
Java
복사
이러한 상황에서 다른 도로 표시 기능을 사용하고 싶다면 어떻게 할까? 혹은 여러 추가 기능을 조합해서 사용하고 싶다면 어떻게 할까?
도로에 교통 상황을 추가로 표시하는 기능을 추가해보자.
public class RoadDisplayWithTraffic extends RoadDisplay { @Override public void draw() { super.draw(); System.out.println("도로 교통량 표시"); } }
Java
복사
하지만 여기서 차선 표시까지 같이하고 싶다면,
public class RoadDisplayWithTraffic extends RoadDisplayWithLane { @Override public void draw() { super.draw(); System.out.println("도로 교통량 표시"); } }
Java
복사
이와 같이 사용 기능을 타고 내려가며 하나씩 바꾸어주어야 한다. 이는 OCP 설계 위반이다.
데코레이터 패턴을 통해 이를 해결할 수 있다.
public abstract class Display { protected Display display; protected Display(final Display display) { this.display = display; } public abstract void draw(); }
Java
복사
public class RoadDisplay extends Display { public RoadDisplay(final Display display) { super(display); } public void draw() { System.out.println("기본 도로 표시"); if (display != null) { display.draw(); } } }
Java
복사
public class RoadDisplayWithLane extends Display { public RoadDisplayWithLane(final Display display) { super(display); } @Override public void draw() { System.out.println("도로 차선 표시"); if (display != null) { display.draw(); } } }
Java
복사
public class RoadDisplayWithTraffic extends Display { public RoadDisplayWithTraffic(final Display display) { super(display); } @Override public void draw() { System.out.println("도로 교통량 표시"); if (display != null) { display.draw(); } } }
Java
복사
기능들이 동일한 추상 클래스를 상속받도록 구현하고,
public class Client { public static void main(String[] args) { final RoadDisplay roadDisplay = new RoadDisplay(null); final RoadDisplayWithLane roadDisplayWithLane = new RoadDisplayWithLane(roadDisplay); final RoadDisplayWithTraffic roadDisplayWithTraffic = new RoadDisplayWithTraffic(roadDisplayWithLane); roadDisplayWithTraffic.draw(); } }
Java
복사
이처럼 클라이언트에서 원하는 기능을 원하는 순서대로 조합하여 사용하면 된다.