> For the complete documentation index, see [llms.txt](https://blakes-organization.gitbook.io/rainsister/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://blakes-organization.gitbook.io/rainsister/design-pattern/proxy-pattern.md).

# Proxy Pattern

{% hint style="info" %}
&#x20;유사한 객체를 포장하는 패턴들을 비교하면&#x20;

* Decorator Pattern : 다른 객체를 포장하고 새로운 행동이나 기능를 추가한다. &#x20;
* Facade Pattern : 다수 객체를 포장해서 interface를 다이어트 시킨다.
* Adapter Pattern : 다른 객체를 포장하고 다른 interface를 제공.
* Proxy Pattern : 다른 객체를 포장하고 접근을 제어 혹은 접근에 초점을 맞춘 용도로 쓴다.
  {% endhint %}

### 정적 프록시

```java
public class TV {

    private String name;//이름

    private String address;//생산지역

    public TV(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "TV{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
```

```java
public interface TVCompany {

    public TV produceTV();
}

```

```java
public class TVFactory implements TVCompany {
    @Override
    public TV produceTV() {
        System.out.println("TV factory produce TV...");
        return new TV("삼성TV","화성공장");
    }
}

```

```java
public class TVProxy implements TVCompany{

    private TVCompany tvCompany;

    public TVProxy(){

    }

    @Override
    public TV produceTV() {
        System.out.println("TV proxy get order .... ");
        System.out.println("TV proxy start produce .... ");
        if(Objects.isNull(tvCompany)){
            System.out.println("machine proxy find factory .... ");
            tvCompany = new TVFactory();
        }
        return tvCompany.produceTV();
    }
}
```

```java
public class TVConsumer {

    public static void main(String[] args) {
        TVProxy tvProxy = new TVProxy();
        TV tv = tvProxy.produceTV();
        System.out.println(tv);
    }
}
```

### 동적 프록시

```java
 public interface TVCompany {

    public TV produceTV();
    
    public TV repair(TV tv);
}
```

```java
public class TVFactory implements TVCompany {
    @Override
    public TV produceTV() {
        System.out.println("TV를 공자에서 만들었습니다.");
        return new TV("삼성TV","화성공장");
    }

    @Override
    public TV repair(TV tv) {
        System.out.println("TV를 수리 완료하였습니다.");
        return new TV("삼성TV","화성공장");
    }
}
```

```java
public class TVProxyFactory {

    private Object target;

    public TVProxyFactory(Object o){
        this.target = o;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("TV proxy find factory for tv.... ");
                Object invoke = method.invoke(target, args);
                return invoke;
            }
        });
    }
}
```

```java
public class TVConsumer {

    public static void main(String[] args) {
        TVCompany target = new TVFactory();
        TVCompany tvCompany = (TVCompany) new TVProxyFactory(target).getProxy();
        TV tv = tvCompany.produceTV();
        tvCompany.repair(tv);
    }
}
```
