Proxy Pattern
프록시 패턴은 객체 간의 간접적인 접근을 가능하게 하는 구조를 제공하는 패턴입니다.
Proxy 클래스를 통해 대신 전달하는 형태로 설계되며, 객체를 바로 호출하는 것이 아닌 Proxy를 호출하는 패턴입니다.
그러므로 실제 Client는 Proxy로 부터 결과를 받습니다.
Proxy의 효과로 캐싱(Caching), 보안(Aop), 데이터 유효성, 지연 초기화, 로깅, 원격객체 등이 있습니다.
객체지향 설계원칙 중 개방폐쇄의 원칙(OCP)과 의존 역전 원칙(DIP)을 따릅니다.
Proxy Pattern 장단점
장점
- 보안성 향상
- 유연성 향상
- 성능 향상
단점
- 코드 복잡성
- 성능 저하
Proxy Pattern 구조
프록시와 객체는 동일한 인터페이스를 가지고 있으며 이를 통해 다른 인터페이스와 완전히 호환되도록 바꿀 수 있습니다.
인터페이스가 있기 때문에 클라이언트는 프록시(Proxy) 와 실제객체(RealSubject) 역할의 차이를 의식할 필요가 없습니다.
클라이언트는 프록시를 중간에 두고 프록시를 통해 실제 객체와 데이터를 주고 받습니다.
프록시는 흐름 제어만 할 뿐 결과값을 조작하거나 변경하면 안됩니다.
Proxy Pattern 종류
- 원격 프록시
- 가상 프록시
- 보호 프록시
Cache Proxy
public interface DisplayIF {
Browser show();
}
public class Browser {
private String text;
public Browser(String text){
this.text = text;
}
}
public class Computer implements DisplayIF {
private String text;
public Computer(String text){
this.text = text;
}
@Override
public Browser show() {
System.out.println("Computer display loading : "+text);
return new Browser(text);
}
}
public class ComputerProxy implements DisplayIF {
private String text;
private Browser browser;
public ComputerProxy(String text){
this.text = text;
}
@Override
public Browser show() {
if(browser == null){
this.browser = new Browser(text);
System.out.println("ComputerProxy display loading : "+text);
}
System.out.println("ComputerProxy display use cache : "+text);
return browser;
}
}
public class ProxyMain {
public static void main(String[] args) {
DisplayIF i = new ComputerProxy("admin");
i.show();
i.show();
}
}
ComputerProxy display loading : admin
ComputerProxy display use cache : admin
ComputerProxy display use cache : admin
Aop Proxy
public class AopComputer implements DisplayIF {
private String text;
private Browser browser;
/** */
private Runnable before;
private Runnable after;
public AopComputer(String text, Runnable before, Runnable after){
this.text = text;
this.before =before;
this.after = after;
}
@Override
public Browser show() {
before.run();
if(browser == null){
this.browser = new Browser(text);
System.out.println("AopComputer browser display loading : "+text);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
after.run();
System.out.println("AopComputer browser cache display loading : "+text);
return null;
}
}
public class AopProxyMain {
public static void main(String[] args) {
AtomicLong start = new AtomicLong();
AtomicLong end = new AtomicLong();
DisplayIF i = new AopComputer("user",
() ->{
System.out.println("before : ");
start.set(System.currentTimeMillis());
},
() ->{
long now = System.currentTimeMillis();
end.set(now - start.get());
});
/** 객체 loading */
i.show();
System.out.println("loading time : "+end.get());
/** 객체를 cache로 불러옴 */
i.show();
System.out.println("loading time : "+end.get());
}
}
before :
AopComputer browser display loading : user
AopComputer browser cache display loading : user
loading time : 2006
before :
AopComputer browser cache display loading : user
loading time : 0
참고
'Spring > 0. Design Pattern' 카테고리의 다른 글
5. 옵저버 패턴(Observer Pattern) (0) | 2024.06.14 |
---|---|
4. 팩토리 메소드 패턴(Factory method pattern) (0) | 2024.06.03 |
2. 어댑터 패턴(Adapter Pattern) (0) | 2022.09.09 |
1. 싱글톤 패턴(Singleton Pattern)과 멀티스레드 환경의 싱글톤 패턴 (0) | 2022.08.01 |