4. 프록시 Proxy Pattern 개념 및 실습

Yeppi's 개발 일기·2022년 5월 13일
0

디자인패턴

목록 보기
4/8
post-thumbnail

1. 개념

대리인

  • 뭔가 대신해서 처리

  • Proxy Class를 통해 대신 전달하는 형태가 설계되고, Client는 Proxy로부터 전달된 결과를 받음

  • Cache 기능으로 활용 가능

  • SOLID 중 개방 폐쇄 원칙(OCP), 의존 역전 원칙(DIP)

Aop 기능

  • 앞 뒤로 넘어가는 기능, 인자 값 조절 가능

  • 흩어져있는 공통된 기능(공통된 method)을 하나로 묶어줄 수 있음


2. 실습

1) 브라우저 기능

  • 브라우저는 매번 새로운 url 로딩, 새롭게 생성된 html 파일을 return 하는 일을 함

  • 반복되는 이 기능을 프록시가 중간(Browser - Clinet)에서 대신 처리

브라우저 인터페이스

  • IBrowser
public interface IBrowser {
    HTML show();
}

일반 브라우저

  • IBrowser 를 상속 받아서 브라우저의 기능을 간략하게 구현
  • Browser
public class Browser implements IBrowser {
    private String url;

    public Browser(String url) {
        this.url = url;
    }

    // 브라우저가 어떤 페이지 동작 시, 매번 새로운 url 을 로딩하고, 새롭게 생성된 해당 HTML 파일을 return
    @Override
    public HTML show() {
        System.out.println("browser loading html from: " + url);
        return new HTML(url);
    }
}

프록시 역할 브라우저

  • 반복되는 url 생성과 html 데이터를 반환해주는 기능을 Cache 형태로 저장
  • Cache 로 한 번 저장되면, 저장된 정보만 뿌려주면 됨
  • BrowserProxy
// Cache 기능을 갖는 Proxy Pattern
public class BrowserProxy implements IBrowser{
    private String url;
    private HTML html;

    public BrowserProxy(String url) {
        this.url = url;
    }

    @Override
    public HTML show() {
        // Cache
        if(html == null) {
            // HTML 에 url 데이터가 없다면, 새롭게 url 을 생성해서 브라우저에 반환
            this.html = new HTML(url);
            System.out.println("BrowserProxy loading html from: " + url);
        }
        // HTML 에 url 데이터가 있다면, 기존에 저장된 url 을 반환 -> Cache
        System.out.println("BrowserProxy use cache html: " + url);
        return html;
    }
}

브라우저에 뿌려줄 코드

  • 프록시 기능을 이해하는 게 먼저이기에 실제 HTML 코드는 작성하지 않았다
public class HTML {
    private String url;
    public HTML(String url) {
        this.url = url;
    }
}

출력 결과

  • main
        // Browser browser = new Browser("www.naver.com");
        // browser.show(); 를 할때마다, url 이 새롭게 계속 할당(loading)되므로 비효율적
        
        // Proxy 를 통해서, Cache(캐시) 를 만들어 url 저장
        IBrowser browser1 = new BrowserProxy("www.naver.com");
        browser1.show(); // 한번만 loading
        browser1.show(); // 동일한 url 은 cache 사용
        browser1.show();
        browser1.show();
        browser1.show();

2) AOP 기능

AOP 브라우저

  • AOP 기능으로 브라우저 기능을 통합
  • AopBrowser
    • 1) 실습에서 진행했던 브라우저, html 기능을 aop 로 모으기
// aop : 특정 패키지에 포함된 모든 method 를 일괄적으로 구현
/* Aop method 특징
    - 기본적으로 before, after method 가 있음
    - 관점지향, 일괄적적 */
    
public class AopBrowser implements IBrowser {
    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(); // html loading time
        
        if(html == null) {
            this.html = new HTML(url);
            System.out.println("AopBrowser html loading from : " + url);
            
            try {
                // method 실행 시간이 너무 짧을 수 있어서 sleep()
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        after.run(); // html loading time
        System.out.println("AopBrowser html cache : " + url);
        return html;
    }
}

출력 결과

  • main
        // Proxy 를 통해서, Aop 기능 구현
        // 시간 method 는 동시성 문제때문에 atomic 사용
        
        AtomicLong start = new AtomicLong();
        AtomicLong end = new AtomicLong();
        
        // Aop 기능 람다식으로 표현
        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()); // 1.5초 + 실행 시간
        aopBrowser.show();
        System.out.println("loading time2 : " + end.get()); // cache 를 사용해서 0초
profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋

0개의 댓글