코딩 기록들

스프링 입문 2.2 프록시(Proxy), 데코레이터(Decorator) 패턴 본문

스프링 입문

스프링 입문 2.2 프록시(Proxy), 데코레이터(Decorator) 패턴

코딩펭귄 2023. 12. 30. 21:26


Proxy pattern
- 대리인 이라는 뜻 = 뭔가를 대신해서 처리하는 것
- proxy class를 통해서 대신 전달하는 형태로 설계됨, 실제client는 proxy로부터 결과를 받는다
- Cache의 기능으로도 활용가능
- SOLID중 개방폐쇄원칙과 의존역전원칙을 따름
- 브라우저, 이미 받아둔 결과를 캐시를 사용해 같은결과 요청시 내려주는 역할을 함

public interface IBrowser {
//html 보여주는 기능
    Html show(); //html로 리턴
}
public class Html {

    private String url;
    //기본 생성자에서 url받아서 html로딩
    public Html(String url){
        this.url = url;
    }
}
public class Browser implements IBrowser{
    private String url;

    public Browser(String url){
        this.url = url;
    }
    @Override
    public Html show() {
        System.out.println("browser loading html from : " + url);
        return new Html(url);
    }
}
public class Main {
    public static void main(String[] args) {

	Browser broswer = new Browser("www.naver.com");
     	broswer.show();
        broswer.show();
        broswer.show();    
    }

 

-> 출력결과 :  캐시기능이 전혀 없음 
browser loading html from : http://www.naver.com
browser loading html from : http://www.naver.com
browser loading html from : http://www.naver.com

 

 -> proxy 패턴 사용하기!

public class BrowserProxy implements IBrowser{

    private String url;
    private Html html;

    public BrowserProxy(String url){
        this.url = url;
    }
    @Override
    public Html show() {
        if(html == null){
            this.html = new Html(url);
            //새로 로딩
            System.out.println("BrowserProxy loading html from "+url);
        }
        System.out.println("BrowserProxy use cache html"); // 캐싱되어있는 html사용
        return html;
    }
}

출력결과

 

 

 

AOP를 활용하는 방법

- proxy패턴 사용

- 특정 메소드에 실행시간, 전후로 작업하고싶은 부분, 일괄적으로 특정요청에 대해 response정보를 남길경우 : 코드에 일괄적으로 특정패키지에 있는 모든메소드를 넣을수있음

- 특정 메소드(ex. show), 기능의 앞뒤로 argument 조작할수있음

 

AOP와 비슷한 프록시패턴 사용예시

메인코드        
        
        AtomicLong start = new AtomicLong();
        AtomicLong end = new AtomicLong();


        IBroswer aopBrowser = new AopBrowser("www.naver.com",
                ()->{
                    System.out.println("before");
                    start.set(System.currentTimeMillis());
                },
                ()->{
                    long now = System.currentTimeMillis();
                    end.set(now - start.get());
                }
        );

        aopBrowser.show();
        System.out.println("loading time : " + end.get());
public class AopBrowser implements IBrowser{

    // AOP특징 : 전후메소드
    private String url;
    private Html html;
    private Runnable before;
    private Runnable after;

    public AopBrowser(String url, Runnable before, Runnable after) {
        this.url = url;
        this.before = before;
        this.after = after;
    }

    @Override
    public Html show() {
        before.run();

        if (html == null){
            this.html = new Html(url);
            System.out.println("AopBrowser html loading from : " + url);
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        after.run();
        System.out.println("AopBrowser html cache : " + url);
        return null;
    }
}

 

 

 

데코레이터 패턴

- 기존뼈대는 유지하되, 이후 필요한 형태로 꾸밀때 사용

- 확장이 필요한 경우 상속의 대안으로 활용

- SOLID중 개방폐쇄원칙(OCP), 의존역전 원칙(DIP)을 따름

- ex. 커피 : 에스프레소 + 물 -> 아메리카노 / 에스프레소 + 우유 -> 카페라떼 처럼 커피원액에 물 or 우유 등 다른재료를 첨가하며 다른형태로 변하게(확장) 되는 경우