2_[spring]데코래이터 패턴
디자인패턴4-데코레이터 패턴
- 구조패턴
- 기존 뼈대(클래스)는 유지하지만, 이후 필요한 형태로 꾸밀 때 사용
- 확장이 필요한 경우 상속의 대안으로도 활용됨
- SOLID 중 개방폐쇄원칙 OCP와 의존역전원칙DIP를 따름
자동차를 예로 들어서 학습해보자!
먼저 자동차라는 기존 뼈대를 두고, 등급별로 가격을 올린다고 생각해보자
데코레이터 패턴
먼저,
- 금액 값을 출력하는 getter메서드 getPrice()
- 자동차 정보와 함께 금액을 출력해주는 showPrice()
가 들어있는 인터페이스인 “ICar”가 있다고 생각해보자
package com.designPattern.structure.decorator;
public interface ICar {
int getPrice();
void showPrice();//금액 출력
}
그리고, 아우디 자동차 회사의 자동차는 이 ICar 인터페이스를 구현하는데
필드로 가격인 price를 가지고 있다고 생각하면 아래와 같이 표현할 수 있다
package com.designPattern.structure.decorator;
public class Audi implements ICar{
private int price;//가격
public Audi(int price){
this.price=price;
}
@Override
public int getPrice() {
return price;
}
@Override
public void showPrice() {
System.out.println("audi의 가격은 "+this.price+" 원 입니다");
}
}
여기서 우리는 이 회사의 자동차의 등급에 따라 금액을 증가시키고 싶고, 등급을 같이 출력해주고 싶다! 그래서, 이 두 속성에 대한 확장을 위해서 “Decorator”클래스로 AudiDecorator를 만들어 주자!
- 필드 : 모델명 modelName, 모델 등급에 따른 증가 금액인 modelPrice
package com.designPattern.structure.decorator;
public class AudiDecorator implements ICar{
protected ICar audi;
protected String modelName;//모델명
protected int modelPrice;//모델 가격
public AudiDecorator(ICar audi, String modelName, int modelPrice){
this.audi = audi;
this.modelName=modelName;
this.modelPrice=modelPrice;
}
@Override
public int getPrice() {
return audi.getPrice()+modelPrice;
}
@Override
public void showPrice() {
System.out.println(modelName+"의 가격은 "+getPrice()+"원 입니다");
}
}
이렇게 모델에 따른 모델 가격을 꾸며주는 decorator를 가지고 이제는 모델에 따라 가격을 보여줄 수 있다! 바로! 이 decorator를 상속받은 concrete decorator로써의 A3, A4, A5를 통해서 아래와 같이 모델명을 입력해주고 생성자에 ICar 인스턴스를 같이 제공해준다면 각 모델 객체가 만들어지게 된다. 뿐만 아니라, 상속을 받기 때문에 AudiDecorator에서 오버라이딩한 내용을 바탕으로 메서드들을 사용할 수 있게 된다!
package com.designPattern.structure.decorator;
public class A3 extends AudiDecorator{
//생성자에 금액은 받지 않고 모델까지만
public A3(ICar audi, String modelName) {
super(audi, modelName,1000);
}
}
package com.designPattern.structure.decorator;
public class A4 extends AudiDecorator{
//생성자에 금액은 받지 않고 모델까지만
public A4(ICar audi, String modelName) {
super(audi, modelName,2000);
}
}
package com.designPattern.structure.decorator;
public class A5 extends AudiDecorator{
//생성자에 금액은 받지 않고 모델까지만
public A5(ICar audi, String modelName) {
super(audi, modelName,3000);
}
}
package com.designPattern.structure.decorator;
public class CarMain {
public static void main(String[] args){
ICar audi = new Audi(1000);
audi.showPrice();//audi의 가격은 1000 원 입니다
//등급을 한번 올려볼것
//a3
ICar audi3 = new A3(audi,"A3");
audi3.showPrice();//A3의 가격은 2000원 입니다
//a4
ICar audi4 = new A4(audi,"A4");
audi4.showPrice();//A4의 가격은 3000원 입니다
//a5
ICar audi5 = new A5(audi,"A5");
audi5.showPrice();//A5의 가격은 4000원 입니다
}
}
그 결과, 위의 CarMain에서처럼, 데코레이터로 인해서 가격 메서드 등이 꾸며졌기 때문에, 각 모델에 따른 금액 변동을 확인해볼 수 있다!
이와 같이 기본 뼈대인 인터페이스를 기반으로, 이를 건드리지 않고, 이를 구현한 클래스를 이용해서 기능을 확장할 수 있는 것이 바로 “데코레이터 패턴”이다!