스프링 핵심 원리(고급편)

Ch04. 프록시 패턴과 데코레이터 패턴 - 데코레이터 패턴

webmaster 2022. 4. 10. 14:53
728x90

데코레이터 패턴 적용 전 - 예제 코드 작성

클레스 다이어그램
런타임 의존관계

서버 - 인터페이스

public interface Component {
    String operation();
}

서버 - 실제 구현 클래스

@Slf4j
public class RealComponent implements Component{

    @Override
    public String operation() {
        log.info("RealComponent 실행");
        return "data";
    }
}

클라이언트 

@Slf4j
public class DecoratorPatternClient {

    private Component component;

    public DecoratorPatternClient(Component component) {
        this.component = component;
    }

    public void execute(){
        String result = component.operation();
        log.info("result={}", result);
    }
}

Test

@Test
public void noDecorator(){
    RealComponent realComponent = new RealComponent();
    DecoratorPatternClient client = new DecoratorPatternClient(realComponent);
    client.execute();
}

데코레이터 패턴 적용 - 예제 코드 작성

데코레이터 패턴: 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행한다.

클레스 다이어그램
런타임 의존관계

데코레이터 페턴 적용 프록시

@Slf4j
public class MessageDecorator implements Component{

    private Component target;

    public MessageDecorator(Component target) {
        this.target = target;
    }

    @Override
    public String operation() {
        log.info("MessageDecorator 실행");

        String result = target.operation();
        String decoResult = "*****" + result + "*****";
        log.info("MessageDecorator 꾸미기 적용 전 = {}, 적용 후 = {}", result, decoResult);
        return decoResult;
    }
}

Test

@Test
public void decorator1() {
    Component realComponent = new RealComponent();
    Component messageDecorator = new MessageDecorator(realComponent);
    DecoratorPatternClient client = new DecoratorPatternClient(messageDecorator);
    client.execute();
}
  • client -> messageDecorator -> realComponent의 객체 의존 관계를 만들고 client.execute()를 호출한다.

데코레이터 패턴 적용 - 체인 적용

클레스 다이어그램
런타임 의존관계

데코레이터 패턴 적용 프록시

@Slf4j
public class TimeDecorator implements Component {

    private Component target;

    public TimeDecorator(Component target) {
        this.target = target;
    }

    @Override
    public String operation() {
        log.info("TimeDecorator 실행");
        long startTime = System.currentTimeMillis();

        String result = target.operation();

        long endTime = System.currentTimeMillis();
        long resultTime = endTime - startTime;
        log.info("TimeDecorator 종료 resultTime={}ms", resultTime);
        return result;
    }
}

Test

@Test
public void decorator2() {
    Component realComponent = new RealComponent();
    Component messageDecorator = new MessageDecorator(realComponent);
    Component timeDecorator = new TimeDecorator(messageDecorator);
    DecoratorPatternClient client = new DecoratorPatternClient(timeDecorator);
    client.execute();
}
  • 클라이언트 코드를 전혀 수정하지 않고 원하는 데코레이터 기능을 연결해주어 호출해 줄 수 있다.
728x90