이번장과 다음장에서는 AOP에서 활용되는 데코레이터, 프록시 패턴에 대해서 소개하고자 한다. 마찬가지로 토비의 스프링 6장에서 소개하는 내용을 정리하고자 기록한다.
데코레이터 패턴은 기본 객체에 추가적인 기능을 동적으로 유연하게 첨가하는 패턴이다.
AOP에서 Aspect를 Joinpoint에 pointcut에 기능을 추가하듯이, 우리가 원하는 추가 로직을 비지니스 로직 앞, 뒤와 같은 위치에 유연하게 첨가하는 패턴을 말한다. 여러개를 추가할 수 있다는 것이 특징이다.
Component
ConcreteComponent 과 Decorator 가 구현할 인터페이스다.
두 객체를 동등하게 다루기 위해 존재함
ConcreteComponent
Decorate 를 받을 객체다.
즉, 비지니스 로직 추가를 받을 기본 객체
Decorator
Decorate 를 할 객체의 추상 클래스다.
즉, 기능 추가를 할 객체는 이 객체를 상속받는다.
ConcreteDecorator
Decorator 를 상속받아 구현할 다양한 기능 객체이다.
이 기능들은 ConcreteComponent 에 추가되기 위해 만들어 진다.
interface ChristmasTree {
String decorate();
}
class DefaultChristmasTree implements ChristmasTree {
@Override
public String decorate() {
return "Christmas tree";
}
}
abstract class TreeDecorator implements ChristmasTree {
private ChristmasTree christmasTree;
public TreeDecorator(ChristmasTree christmasTree) {
this.christmasTree = christmasTree;
}
@Override
public String decorate() {
return christmasTree.decorate();
}
}
class Lights extends TreeDecorator {
public Lights(ChristmasTree christmasTree) {
super(christmasTree); // 여기가 포인트.
}
public String addLights() {
return " with Lights";
}
@Override
public String decorate() {
return super.decorate() + addLights(); // 여기가 포인트.
}
}
class Flowers extends TreeDecorator {
public Flowers(ChristmasTree christmasTree) {
super(christmasTree);
}
public String addFlowers() {
return " with Flowers";
}
@Override
public String decorate() {
return super.decorate() + addFlowers();
}
}
public class DecoratorDemo {
public static void main(String[] args) {
// Christmas tree 만 있음.
ChristmasTree tree = new DefaultChristmasTree();
System.out.println(tree.decorate());
// Christmas tree + Lights
ChristmasTree treeWithLights = new Lights(
new DefaultChristmasTree()
);
System.out.println(treeWithLights.decorate());
// Christmas tree + Lights + Flowers
ChristmasTree treeWithLightsAndFlowers = new Flowers(
new Lights(
new DefaultChristmasTree()
)
);
System.out.println(treeWithLightsAndFlowers.decorate());
}
}