에릭 프리먼 님의 "헤드퍼스트 디자인 패턴" 책을 정리한 포스팅 입니다
1. 프록시 패턴
- 다른 객체에 대한 접근을 제어하기 위해 그 객체의 대리인을 사용하는 디자인패턴
- 원래 객체에 직접 접근하는 것이 아닌, 프록시를 통해 간접적으로 접근하도록 함
구성 요소
| 구성 요소 | 설명 | 
| Subject(인터페이스) | 원래 객체와 프록시가 공통으로 구현하는 인터페이스 | 
| RealSubject | 실제 작업을 수행하는 객체 | 
| Proxy | RealSubject에 대한 접근을 제어하는 대리 객체 | 
사용처
| 목적 | 설명 | 
| 접근 제어 | 보안, 인증, 권한 제어를 위해 직접 접근 대신 프록시에서 제어함 | 
| 지연 초기화 | 무거운 객체의 생성/로딩을 실제 필요 시점까지 미루기 위해 사용 | 
| 원격 호출 | 네트워크나 다른 JVM에 있는 객체와 통신하기 위한 로컬 대리 객체 제공 | 
| 부가 기능 추가 | 성능 측정, 캐싱, 로깅 등의 기능을 원본 객체에 영향을 주지 않고 프록시에서 처리함 | 
2. 예제: Dating
Person
- 자신의 정보를 직접 수정하는 것을 막아야 함
더보기
public interface Person {
    String getName();
    String getGender();
    String getInterests();
    int getGeekRating();
    
    void setName(String name);
    void setGender(String gender);
    void setInterests(String interests);
    void setGeekRating(int rating);
}
Proxy
- 프록시의 행동을 구현
더보기
InvocationHander (java.lang.reflect)
public interface InvocationHandler { 	
    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;        
}public class OwnerInvocationHandler implements InvocationHandler {
    Person person;
    
    public OwnerInvocationHandler(Person person) { this.person = person; }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException {
    	try {
            if (method.getName().equals("setGeekRating") throw new IllegalAccessException();
            
            if (method.getName().startsWith("get") || method.getName().startsWith("set")) return method.invoke(person, args);            
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        
        return null;
    }
}- 자신 핸들러
- 클라이언트용 핸들러
동적 프록시 생성
더보기
Person getOwnerProxy(Person person) {
    return (Person) Proxy.newProxyInstance(
    	person.getClass().getClassLoader(),
        person.getClass().getInterfaces(),
        new OwnerInvocationHandler(person));
}
3. 원격 프록시
- 원격 객체의 로컬 대변자
- 어떤 메서드를 호출하면, 다른 원격 객체에게 그 메서드 호출을 전달해 주는 객체
| 항목 | 설명 | 
| 목적 | 클라이언트가 로컬 객체처럼 사용할 수 있게 하면서, 내부적으로는 원격 호출 처리 | 
| 클라이언트 역할 | 원격 객체가 로컬에 있는 것처럼 메서드를 호출 | 
| 프록시 역할 | 저수준 작업 담당 (네트워크 연결, 요청 전송, 응답 수신, 예외 처리 등) | 
| 원격 객체 역할 | 실질적인 비즈니스 로직 수행 (서버 측 객체) | 
4. 예시: RMI
- 자바의 원격 메서드 호출 기능
- 클라이언트와 서버 간 통신을 자동화
| 구성 요소 | 설명 | 역할 | 
| Stub | 클라이언트 측 보조 객체 원격 객체를 로컬처럼 호출하게 해줌 | 클라이언트 → 서버 호출 프록시 | 
| Skeleton | 서버 측 보조 객체 요청을 실제 객체에 전달하고 결과를 반환함 | 요청 디코딩 → 실제 객체 실행 | 
| Remote Object | 실제 비즈니스 로직을 수행하는 서버 측 객체 | 원격으로 호출되는 진짜 대상 | 
'Java > Design Pattern' 카테고리의 다른 글
| [헤드퍼스트 디자인 패턴] 12-2. 빌더 패턴 (0) | 2024.12.19 | 
|---|---|
| [헤드퍼스트 디자인 패턴] 12-1. 브리지 패턴 (0) | 2024.12.18 | 
| [헤드퍼스트 디자인 패턴] 10. 상태 패턴 (0) | 2024.12.18 | 
| [헤드퍼스트 디자인 패턴] 9-2. 컴포지트 패턴 (2) | 2024.12.18 | 
| [헤드퍼스트 디자인 패턴] 9-1. 반복자 패턴 (0) | 2024.12.18 |