-
5. 데커레이터 패턴(Decorator Pattern)디자인패턴 2021. 12. 30. 16:47
데커레이터 패턴이란?
데커레이터 패턴은 기본 기능에 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 Decorator 클래스로
정의한 후 필요한 Decorator 객체를 조합함으로써 추가 기능의 조합을 설계하는 방식이다.
프로그램을 실행하는 중에도 Decorator 객체의 조합이 가능하므로 필요한 추가 기능의 조합을 동적으로 생성하는 것도 가능하다.
아래 예시는 데커레이터 패턴을 적용하기 전 예시이다.
네비게이션 SW에서 도로를 표시하는 기능을 생각해보자.
1. 기본 도록 표시 기능
2. 차선 표시 기능//기본 도로 표시 클래스 public class RoadDisplay{ public void draw(){ System.out.println("기본 도로 표시"); } } //기본 도로 표시 + 차선 표시 클래스 public class RoadDisplayWithLane extends RoadDisplay{ public void draw(){ super.draw(); //상위 클래스, 즉 RoadDisplay 클래스의 draw 메서드를 호출해서 기본 도로를 표시 drawLane(); //추가적으로 차선을 표시 } private void drawLane(){ System.out.println("차선 표시"); } //클라이언트 클래스 public class Client{ public static void main(String[] args){ RoadDisplay road = new RoadDisplay(); road.draw(); //기본 도로만 표시 RoadDisplay roadWithLane = new RoadDisplayWithLane(); roadWithLane.draw(); //기본 도로 + 차선 표시 } } }
위의 예제 코드는 기본 기능을 RoadDisplay 클래스에 정의한 후
추가기능이 생기면 추가기능 클래스에 RoadDisplay를 상속받아 메소드를 오버라이드해서 사용한다.
만약 여기서 추가기능이 A, B, C ... 계속 늘어나고 해당 기능들을 조합해서 사용해야한다면 구조는 상당히 복잡해진다.모든 추가기능 클래스가 RoadDisplay 를 상속받아 구현해야하기 때문이다.
데커레이터 패턴을 적용하여 아래 예시와 같이 바꿔보자.
//Display 추상 클래스 public abstract class Display{ public abstract void draw(); } //기본 도로 표시 클래스 public class RoadDisplay extends Display{ public void draw(){ System.out.println("기본 도로 표시"); } } //다양한 추가 기능에 대한 공통 클래스 public abstract class DisplayDecorator extends Display{ private Display decorateDisplay; public DisplayDecorator(Display decoratedDisplay){ this.decoratedDisplay = decoratedDisplay; } public void draw(){ decoratedDisplay.draw(); } } //차선 표시를 추가하는 클래스 public class LaneDecorator extends DisplayDecorator{ public LaneDecorator(Display decoratedDisplay){ //기본 표시 클래스의 설정 super(decoratedDisplay); } public void draw(){ super.draw(); //설정된 기존 표시 기능을 수행 drawLane(); //추가적으로 차선을 표시 } private void drawLane(){ System.out.println("\t차선 표시"); } } //교통량 표시를 추가하는 클래스 public class TrafficDecorator extends DisplayDecorator{ public TrafficDecorator(Display decoratedDisplay){ //기존 표시 클래스의 설정 super(decoratedDisplay); } public void draw(){ super.draw(); //설정된 기존 표시 기능을 수행 drawTraffic(); //추가적으로 교통량을 표시 } private void drawTraffic(){ System.out.println("\t교통량 표시"); } }
위처럼 구성된 코드는 클라이언트에서 아래처럼 사용할 수 있다.
//클라이언트 클래스 public class Client{ public static void main(String[] args){ Display road = new RoadDisplay(); road.draw(); //기본 도로 표시 Display road = new LaneDecorator(new RoadDisplay()); road.draw(); //기본 도로 표시 + 차선 표시 Display road = new TrafficDecorator(new RoadDisplay()); road.draw(); //기본 도로 표시 + 교통량 표시 } }
[실행결과]
기본 도로 표시
기본 도로 표시
차선표시
기본 도로 표시
교통량 표시현재는
1. 기본 도로 표시 + 차선 표시
2. 기본 도로 표시 + 교통량 표시
이렇게만 구성되어있지만 이후에
3. 기본 도로 표시 + 차선 표시 + 교통량 표시
기능을 조합하여 만들고 싶다면 아래처럼 사용하면 된다.
//클라이언트 클래스 public class Client{ public static void main(String[] args){ Display roadWithLaneAndTraffic = new TrafficDecorator(new LaneDecorator(new RoadDisplay())); roadWithLaneAndTraffic.draw(); } }
[실행결과]
기본 도로 표시
차선표시
교통량 표시한마디로 정리하자면 데코레이터 패턴은 기본 기능에 추가할 수 있는 많은 종류의 부가 기능에서 파생되는 다양한 조합을 동적으로 구현할 수 있는 패턴이다.
해당 포스트는 JAVA 객체지향 디자인패턴을 읽은 후 기록한 내용입니다.
참고서적링크 : https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=38792551
자바 객체지향 디자인 패턴
체계적인 학습법을 바탕으로 설명하는 객체지향 디자인 패턴의 교과서. 자바와 UML을 중심으로 객체지향 이론이 무엇인지를 배운 다음 GoF에서 소개하는 디자인 패턴의 핵심 10가지를 알기 쉽게
www.aladin.co.kr
이미지 아이콘 출처: https://www.flaticon.com/free-icon/pattern-lock_4643427?term=pattern&related_id=4643427
'디자인패턴' 카테고리의 다른 글
4. 옵서버 패턴(Observer Pattern) (0) 2021.12.22 3. 커맨드 패턴(Command Pattern) (0) 2021.12.20 2. 싱글톤 패턴(Singleton Pattern) (0) 2021.11.16 1. 스트래티지 패턴(Stragety Pattern) (0) 2021.11.08