디자인패턴 4. Proxy Pattern

min seung moon·2021년 6월 25일
0

Spring

목록 보기
9/50

1. Proxy Pattern

  • Proxy는 대리인 이라는 뜻으로써, 뭔가를 대신해서 처리하는 것
  • Proxy Class를 통해서 대신 전달하는 형태로 설계되며, 실제 CLient는 Proxy로 부터 결과를 받는다
  • Cache의 기능으로도 활용이 가능하다
  • SOLID 중에서 개방폐쇄 원칙(OCP)과 의존 역전 원칙(DIP)를 따른다

2. 프로젝트 테스트

  • proxy 패키지 생성
  • Interface : IBrowser
  • Class : Html, Browser

01. Cache 기능 추가 전

  • IBrowser.java
package com.company.design.proxy;

public interface IBrowser {
    Html show();
}
  • Html.java
package com.company.design.proxy;

public class Html {

    private String url;

    public Html(String url) {
        this.url = url;
    }
}
  • Browser.java
package com.company.design.proxy;

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);
    }
}
  • Main.java
package com.company.design;

import com.company.design.proxy.Browser;

public class Main {

    public static void main(String[] args) {
        Browser browser = new Browser("www.naver.com");
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        browser.show();
    }
}
  • 매번 새로운 Html이 loading 된다

02. Cache 기능 추가

  • Cache는 브라우저에서 지원을 해줘야한다
    • class : BrowserProxy 생성
  • BrowserProxy.java
package com.company.design.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 "+ url);

        return html;
    }
}
  • Main.java
package com.company.design;

import com.company.design.proxy.Browser;
import com.company.design.proxy.BrowserProxy;
import com.company.design.proxy.IBrowser;

public class Main {

    public static void main(String[] args) {
        /*
        Browser browser = new Browser("www.naver.com");
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        browser.show();
         */

        IBrowser browser = new BrowserProxy("www.naver.com");
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        browser.show();
    }
}

03. AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)

  • 특정한 메소드가 있으면 메소드의 실행 시간이라던지 또는 특정한 패키지의 특정한 메소드들의 실행시간 또는 전후 작업하고 싶은 부분들
  • 일괄적으로 특정한 요청에 대해서 request 정보를 남긴다던지 response 정보를 담긴다던지 코드에 다가 개별적으로 하는게 아닌 일괄적으로 특정 패키지에 모든 메소드들을 이런 형식으로 전후에 기능을 넣을 수 있는 부분
  • 특정 메소드가 얼마나 시간이 걸렸는지, 시스템에서 특정 메소드가 시간이 얼마나 걸리는지 측정할 때도 사용

-1. Proxy로 AOP 구성

  • Package : aop
  • Class : AopBrowser
  • AopBrowser.java
package com.company.design.apo;

import com.company.design.proxy.Html;
import com.company.design.proxy.IBrowser;

public class AopBrowser implements IBrowser {

    private String url;
    private Html html;
    // 앞과 뒤 체크를 위한 @FunctionalInterface
    // run() 추상 메소드를 가지고 있다, 람다식으로 표현 가능
    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) {
            html = new Html(url);
            System.out.println("AopBrowser html loading from " + url);
            // 메소드가 빠를 수 있기에 조금의 틈을 준다
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        after.run();
        
        System.out.println("AopBrowser html cache " + url);
        return html;
    }
}
  • Main.java
package com.company.design;

import com.company.design.apo.AopBrowser;
import com.company.design.proxy.Browser;
import com.company.design.proxy.BrowserProxy;
import com.company.design.proxy.IBrowser;

import java.util.concurrent.atomic.AtomicLong;

public class Main {

    public static void main(String[] args) {
        /*
        Browser browser = new Browser("www.naver.com");
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        browser.show();


        IBrowser browser = new BrowserProxy("www.naver.com");
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        browser.show();
        */

        // 시간 체크, 동시성 문제로 AtomicLong을 사용
        AtomicLong start = new AtomicLong();
        AtomicLong end = new AtomicLong();

        IBrowser 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());

        aopBrowser.show();
        System.out.println("loading time : " + end.get());
    }
}

profile
아직까지는 코린이!

0개의 댓글