본문 바로가기
개발/디자인 패턴

[Java 언어로 배우는 디자인 패턴 입문] 낭비 없애기 21. Proxy

by hongdor 2021. 1. 17.
728x90

출처 : 책 - java 언어로 배우는 디자인 패턴 입문

 

21. Proxy - 필요해지면 만들기

 

 

1. 목적

 

 - Proxy의 뜻은 '대리인'이다. 가벼운 인을 대리인이 처리하도록 하는 방법이다.

 - 가벼운 처리와 무거운 처리를 구분 하므로써 속도가 향상된다. 

  Ex) 무거운 파일들 중 가벼운 파일만 불러올 경우, 전체를 다 가져올 필요는 없다.

 - 물론 Proxy를 만들지 않고, 오리지날 클래스에 필요할 때 그때 인스턴스 생성을 하게 할 수 있다.

   하지만 Proxy를 만들면 오리지날 클래스를 건들지 않고 대리인만 수정하여 대신할 일을 정할 수 있다.

   만약 Main에서 Proxy를 사용하고 싶지 않을경우 바로 오리지날 인스턴스를 생성해 넣어주면 된다. 

 

 cf) HTTP Proxy : 크롬같은 브라우저에서 웹페이지 표시 시 네이버같은 회사의 웹서버에 액세스해서 페이지 정보를 가져온다.

                            여기서 HTTP Proxy가 웹서버에서 페이지를 대신 가져와 저장한다.

                            그리고 브라우저는 HTTP Proxy에서 페이지 정보를 가져온다.

                            웹서버가 본인이고 HTTP Proxy가 Proxy, 웹브라우저가 Client 역할을 한다. 

 

 

2. 예제 

 

(1) Printable - 인터페이스. Printer와 PrinterProxy 상위 인터페이스

public interface Printable {
    public abstract void setPrinterName(String name);   // 이름의 설정
    public abstract String getPrinterName();            // 이름의 취득
    public abstract void print(String string);          // 문자열 표시(프린트 아웃)
}

 

 

(2) Printer - 무거운 클래스( 생성 자체가 Heavy )

public class Printer implements Printable {
    private String name;
    public Printer() {
        heavyJob("Printer의 인스턴스를 생성 중");
    }
    public Printer(String name) {                   // 생성자
        this.name = name;
        heavyJob("Printer의 인스턴스 (" + name + ")을 생성 중");
    }
    public void setPrinterName(String name) {       // 이름의 설정
        this.name = name;
    }
    public String getPrinterName() {                // 이름의 취득
        return name;
    }
    public void print(String string) {              // 이름을 붙여 표시
        System.out.println("=== " + name + " ===");
        System.out.println(string);
    }
    private void heavyJob(String msg) {             // 무거운 일(의 예정)
        System.out.print(msg);
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            System.out.print(".");
        }
        System.out.println("완료");
    }
}

 

 

(3) PrinterProxy - Printer 클래스의 대리인. 

public class PrinterProxy implements Printable {
    private String name;          // 이름
    private Printer real;           // 「본인」
    public PrinterProxy() {
    }
    public PrinterProxy(String name) {      // 생성자
        this.name = name;
    }
    public synchronized void setPrinterName(String name) {  // 이름의 설정
        if (real != null) {
            real.setPrinterName(name);  // 「본인」에게도 설정한다
        }
        this.name = name;
    }
    public String getPrinterName() {     // 이름의 설정
        return name;
    }
    public void print(String string) {     // 표시
        realize();
        real.print(string);
    }
    private synchronized void realize() {   // 「본인」을 생성
        if (real == null) {            
            real = new Printer(name);
        }                           
    }
}

 

 

(4) Main

public class Main {
    public static void main(String[] args) {
        Printable p = new PrinterProxy("Alice");
        System.out.println("이름은 현재 " + p.getPrinterName() + "입니다.");
        p.setPrinterName("Bob");
        System.out.println("이름은 현재 " + p.getPrinterName() + "입니다.");
        p.print("Hello, world.");
    }
}

 

 

728x90

댓글