티스토리 뷰

프록시 주요 기능 두 가지

  • 접근 제어
    • 권한에 따른 접근 차단
    • 캐싱
    • 지연 로딩
  • 부가 기능 추가
    • 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행
      • e.g. 요청 값이나 응답 값 변형
      • e.g. 실행 시간을 측정해서 로그를 추가한다.

프록시 패턴 vs 데코레이터 패턴

  • 프록시를 사용하는 목적(의도)에 따라 구분.
  • 프록시 패턴
    • 접근 제어
  • 데코레이터 패턴
    • 부가 기능 추가

프록시 패턴

코드 예시

  • 데이터를 cache 하는 프록시 예제
public interface Subject {
    String operation();
}

public class RealSubject implements Subject{
    @Override
    public String operation() {
        log.info("실제 객체 호출");
        sleep(1000);
        return "data";
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class CacheProxy implements Subject{

    private Subject target;
    private String cacheValue;

    public CacheProxy(Subject target) {
        this.target = target;
    }

    @Override
    public String operation() {
        log.info("프록시 호출");
        if (cacheValue == null) {
            cacheValue = target.operation();
        }
        return cacheValue;
    }
}
public class ProxyPatternTest {

    @Test
    void noProxyTest() {
        RealSubject realSubject = new RealSubject();
        ProxyPatternClient client = new ProxyPatternClient(realSubject);
        client.execute();
        client.execute();
        client.execute();
    }

    @Test
    void cacheProxyTest() {
        RealSubject realSubject = new RealSubject();
        CacheProxy cacheProxy = new CacheProxy(realSubject);
        ProxyPatternClient client = new ProxyPatternClient(cacheProxy);
        client.execute();
        client.execute();
        client.execute();
    }
}

프록시 패턴 정리

  • RealSubject (target) 과 클라이언트 코드 변경 없이 ‘접근 제어’를 구현할 수 있다.
    • 클라이언트 코드 변경 없이 프록시를 넣거나 뺄 수 있다.

데코레이터 패턴

코드 예시

  • 반환값을 수정하고, 시간을 측정하는 부가 기능 추가
public interface Component {
    String operation();
}


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


public abstract class Decorator implements Component {
    protected Component component;

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

    @Override
    public abstract String operation();
}

public class MessageDecorator extends Decorator{

    // private Component component;
    //
    // public MessageDecorator(Component component) {
    //     this.component = component;
    // }

    public MessageDecorator(Component component) {
        super(component);
    }

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

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

public class TimeDecorator extends Decorator{

    // private Component component;
    //
    // public TimeDecorator(Component component) {
    //     this.component = component;
    // }

    public TimeDecorator(Component component) {
        super(component);
    }

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

        String result = component.operation();

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

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

    @Test
    void decorator1() {
        Component realComponent = new RealComponent();
        Component messageDecorator = new MessageDecorator(realComponent);
        DecoratorPatternClient client = new DecoratorPatternClient(messageDecorator);
        client.execute();
    }

    @Test
    void decorator2() {
        Component realComponent = new RealComponent();
        Component messageDecorator = new MessageDecorator(realComponent);
        TimeDecorator timeDecorator = new TimeDecorator(messageDecorator);
        DecoratorPatternClient client = new DecoratorPatternClient(timeDecorator);
        client.execute();
    }
}

출처

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함