일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- 카카오테크 부트캠프
- 골드3
- 도커
- 스프링 부트
- BFS
- express.js
- 인스턴스
- 정보처리기사
- 백준 알고리즘
- 자바
- 자료구조
- 배포
- 알고리즘
- 대전
- 엘라스틱빈스톡
- 정처기
- 코딩테스트 고득점 kit
- 스프링부트
- 한국전자통신연구원
- DFS
- 카테부
- EC2
- ETRI
- 디자인패턴
- 골드4
- 골드5
- Express
- 프로그래머스
- aws
- DP
Archives
JUINTINATION
데커레이터(Decorator) 패턴 본문
반응형
데커레이터 패턴이란?
기본 기능에 추가할 수 있는 기능의 종류가 많은 경우 기본 기능에 추가될 수 있는 많은 수의 부가 기능에 대해서 다양한 조합을 동적으로 구현할 수 있는 패턴이다.
다음과 같이 도로를 여러 가지 표시하는 프로그램이 있다고 하자.
public class Client {
public static void main(String[] args) {
RoadDisplay roadDisplay = new RoadDisplay();
roadDisplay.draw();
RoadDisplayWithLane roadDisplayWithLane = new RoadDisplayWithLane();
roadDisplayWithLane.draw();
}
}
class RoadDisplay {
public void draw() {
System.out.println("기본 도로 표시");
}
}
class RoadDisplayWithLane extends RoadDisplay {
@Override
public void draw() {
super.draw();
drawLane();
}
private void drawLane() {
System.out.println("차선 표시");
}
}
- 위 코드의 문제점
- 여러 가지 추가 기능을 조합하여 도로를 표시하는 방법을 바꾸고 싶다면 각 기능을 중복되게 작성하여 각각의 클래스를 만들어야 한다.
경우 | 기본 기능 도로 표시 | 추가 기능 | 클래스 이름 | ||
차선 표시 | 교통량 표시 | 교차로 표시 | |||
1 | O | RoadDisplay | |||
2 | O | O | RoadDisplayWithLane | ||
3 | O | O | RoadDisplayWithTraffic | ||
4 | O | O | RoadDisplayWithCrossing | ||
5 | O | O | O | RoadDisplayWithLaneTraffic | |
6 | O | O | O | RoadDisplayWithLaneCrossing | |
7 | O | O | O | RoadDisplayWithTrafficCrossing | |
8 | O | O | O | O | RoadDisplayWithLaneTrafficCrossing |
이를 해결하기 위해 다음과 같이 추가 기능별로 개별적인 클래스를 설계하고 이를 조합한다.
public class Client {
public static void main(String[] args) {
Display roadWithLaneTrafficCrossingDisplay = new LaneDecorator(new TrafficDecorator(new CrossingDecorator(new RoadDisplay())));
roadWithLaneTrafficCrossingDisplay.draw();
}
}
abstract class Display {
abstract void draw();
}
class RoadDisplay extends Display {
@Override
void draw() {
System.out.println("기본 도로 표시");
}
}
abstract class DisplayDecorator extends Display {
private Display decoratedDisplay;
public DisplayDecorator(Display decoratedDisplay) {
this.decoratedDisplay = decoratedDisplay;
}
@Override
void draw() {
decoratedDisplay.draw();
}
}
class LaneDecorator extends DisplayDecorator {
public LaneDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw();
drawLane();
}
private void drawLane() {
System.out.println("차선 표시");
}
}
class TrafficDecorator extends DisplayDecorator {
public TrafficDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw();
drawTraffic();
}
private void drawTraffic() {
System.out.println("교통량 표시");
}
}
class CrossingDecorator extends DisplayDecorator {
public CrossingDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw();
drawCrossing();
}
private void drawCrossing() {
System.out.println("교차로 표시");
}
}
데커레이터 패턴 컬레보레이션
Component : 기본 기능을 뜻하는 ConcreteComponent와 추가 기능을 뜻하는 Decorator의 공통 기능을 정의한 추상 클래스
ConcreteComponent : 기본 기능을 구현하는 클래스
Decorator : 추가 기능의 공통 기능을 정의한 추상 클래스
ConcreteDecorator : 기본 기능의 추가되는 개별적인 기능을 정의한 Decorator의 하위 클래스
데커레이터 패턴을 이용한 간단한 예제
다음과 같은 이메일 내용과 관련된 기능을 구현한 프로그램 코드와 클래스 다이어그램이 있을 때 데커레이터 패턴을 적용하여 프로그램 기능을 개선하라.
class BasicEMailContent {
private String content;
public BasicEMailContent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
class ExternalEMailContent extends BasicEMailContent {
public ExternalEMailContent(String content) {
super(content);
}
@Override
public String getContent() {
return addDisclaimer(super.getContent());
}
private String addDisclaimer(String content) {
return content + " Company Disclaimer";
}
}
class SecureEMailContent extends BasicEMailContent {
public SecureEMailContent(String content) {
super(content);
}
@Override
public String getContent() {
return encrypt(super.getContent());
}
private String encrypt(String content) {
return content + " Encrypted";
}
}
- 위 코드의 문제점
- ExternalEMailContent와 SecureEMailContent의 조합을 추가하기 위해 각 기능을 중복되게 작성하여 새로운 클래스를 만들어야 한다.
이 문제를 해결하기 위해 다음과 같이 코드와 클래스 다이어그램을 수정해야 한다.
abstract class EMailContent {
public abstract String getContent();
}
class BasicEMailContent extends EMailContent {
private String content;
public BasicEMailContent(String content) {
this.content = content;
}
@Override
public String getContent() {
return content;
}
}
abstract class ContentDecorator extends EMailContent {
private EMailContent decoratedContent;
public ContentDecorator(EMailContent decoratedContent) {
this.decoratedContent = decoratedContent;
}
@Override
public String getContent() {
return decoratedContent.getContent();
}
}
class ExternalDecorator extends ContentDecorator {
public ExternalDecorator(EMailContent decoratedContent) {
super(decoratedContent);
}
@Override
public String getContent() {
return addDisclaimer(super.getContent());
}
private String addDisclaimer(String content) {
return content + " Company Disclaimer";
}
}
class SecureDecorator extends ContentDecorator {
public SecureDecorator(EMailContent decoratedContent) {
super(decoratedContent);
}
@Override
public String getContent() {
return encrypt(super.getContent());
}
private String encrypt(String content) {
return content + " Encrypted";
}
}
반응형
'JAVA객체지향디자인패턴' 카테고리의 다른 글
팩토리 메서드(Factory Method) 패턴 (1) | 2023.07.16 |
---|---|
템플릿 메서드(Template Method) 패턴 (0) | 2023.07.16 |
옵서버(Observer) 패턴 (0) | 2023.07.06 |
커맨드(Command) 패턴 (0) | 2023.07.06 |
스테이트(State) 패턴 (0) | 2023.07.06 |
Comments