디자인 패턴 중 하나인 데코레이터 패턴에 대해 포스팅합니다.
목차
- 데코레이터 패턴이란?
- 데코레이터 패턴 예제
데코레이터 패턴이란?
데코레이터 패턴은 기존 뼈대(클래스)는 유지하되 이후 필요한 형태로 꾸미기 위해 사용합니다. 기존 객체의 확장이 필요한 경우 상속의 대안으로도 활용합니다. SOLID 중 개방 폐쇄 원칙과(OCP)와 의존 역전 원칙(DIP)을 따릅니다.
현실세계를 예로 들면 케이크를 예로 들 수 있습니다. 기본 케이크 빵에 생크림을 추가하면 생크림케이크가 되고, 초코를 추가하면 초콜릿 케이크가 됩니다. 또 딸기를 추가하면 딸기 케이크가 될 수 있습니다. 이처럼, 케이크는 기존의 모습을 유지하고 어떤 것을 꾸미느냐에 따라 결과물이 달라질 수 있습니다.
데코레이터 패턴 예제
데코레이터 패턴은 자동차를 구매하는 것으로 예를 들어보겠습니다. 자동차를 구매할 때 한 브랜드에 소형, 중형, 대형 등 등급이 나뉘어 있고 등급에 따라 옵션과 가격이 다른데요. 이해하기 쉽게 기아자동차의 K시리즈를 예로 들어 설명하겠습니다.
자동차 인터페이스
자동차 인터페이스는 가격을 알려주는 getPrice 메서드와 가격을 출력하는 showPrice 메서드를 갖습니다.
public interface ICar {
int getPrice();
void showPrice();
}
브랜드 클래스
브랜드는 KIA로 하겠습니다. KIA의 K시리즈를 예로 들어 설명하겠습니다. KIA 클래스는 ICar 인터페이스를 구현한 구현체입니다. KIA는 가격을 갖고 있고 ICar에서 갖고 있는 getPrice와 showPrice를 구현했습니다. getPrice는 price를 리턴하고 showPrice는 Kia의 가격을 출력해줍니다.
public class Kia implements ICar {
private int price;
public Kia(int price) {
this.price = price;
}
@Override
public int getPrice() {
// TODO Auto-generated method stub
return price;
}
@Override
public void showPrice() {
// TODO Auto-generated method stub
System.out.println("Kia의 가격은 "+ this.price + "원 입니다.");
}
}
데코레이션 클래스
기아에서 새로운 자동차 모델을 낼 때마다 자동차 인터페이스를 구현하지 않고 데코레이터 클래스를 사용해 새로 생성만 하도록 하겠습니다. KiaDecorator는 ICar 인터페이스를 구현하고 ICar 인터페이스, 모델명, 모델 가격을 변수로 갖습니다. getPrice는 자동차 인터페이스의 기본 가격에 모델 가격을 더해서 리턴해줍니다. showPrice는 각 model명의 가격을 출력해줍니다.
public class KiaDecorator implements ICar{
private ICar icar;
private String modelName;
private int modelPrice;
public KiaDecorator(ICar icar, String modelName, int modelPrice) {
this.icar = icar;
this.modelName = modelName;
this.modelPrice = modelPrice;
}
@Override
public int getPrice() {
return icar.getPrice() + this.modelPrice;
}
@Override
public void showPrice() {
System.out.println(modelName + "은 " + getPrice() + "원 입니다.");
}
}
모델 클래스
각 K3, K5, K7 모델은 출시할 때 모델명과 가격을 정하게 되고요. 구매자는 모델을 정하면 가격을 알게됩니다. 모델 클래스에서 자동차 인터페이스와 모델명을 받으면 KiaDecorator 클래스의 생성자를 호출하여 자동차 인터페이스, 모델명, 가격을 넘겨 객체를 생성합니다.
public class K3 extends KiaDecorator {
public K3(ICar icar, String modelName) {
super(icar, modelName, 1000);
}
}
public class K5 extends KiaDecorator {
public K5(ICar icar, String modelName) {
super(icar, modelName, 2000);
}
}
public class K7 extends KiaDecorator {
public K7(ICar icar, String modelName) {
super(icar, modelName, 3000);
}
}
Main Class
이제 기아자동차에 가격을 문의해보겠습니다. 기아에서 기본자동차를 살 경우 가격은 1,000원입니다. 이번엔 모델을 정해서 자동차 가격을 문의해보겠습니다. K3 모델을 문의하면 2,000원, K5는 3,000원, K7은 4,000원이 출력됩니다.
public class DecoratorMain {
public static void main(String[] args) {
ICar kia = new Kia(1000);
kia.showPrice();
// k3
ICar k3 = new K3(kia, "K3");
k3.showPrice();
// k5
ICar k5 = new K5(kia, "K5");
k5.showPrice();
// k7
ICar k7 = new K7(kia, "K7");
k7.showPrice();
}
}
=> 실행결과
Kia의 가격은 1000원 입니다.
K3은 2000원 입니다.
K5은 3000원 입니다.
K7은 4000원 입니다.
이렇듯, 데코레이터 패턴을 사용하면 자동차 인터페이스와 각 모델은 변경하지 않고 데코레이터 클래스를 사용하여 가격정보 또는 옵션 정보 등을 다르게 저장, 출력할 수 있게 됩니다.
'SPRING' 카테고리의 다른 글
파사드 패턴이란? (1) | 2022.04.01 |
---|---|
옵저버 패턴이란? (1) | 2022.04.01 |
[파트 1. 스프링 입문] 챕터 2-4. 프록시 패턴 (1) | 2022.03.24 |
[파트 1. 스프링 입문] 챕터 2-3. 어댑터 패턴 (2) | 2022.03.14 |
[파트 1. 스프링 입문] 챕터 2-2. 싱글톤 패턴 (2) | 2022.03.14 |
댓글