디자인 모델 탐색 - 대리 모델

6700 단어 디자인 모드
대리 모델 은 매우 중요 한 디자인 모델 로 자바 언어 에서 광범 위 하 게 응용 되 고 Spring AOP 의 핵심 디자인 사상 을 포함 하여 모두 대리 모델 과 밀접 한 관 계 를 가진다.
프 록 시 모드 는 주로 두 가지 로 나 뉜 다. 하 나 는 정적 에이전트 이 고 하 나 는 동적 에이전트 이다.두 가지 대리 방식 의 실현 은 본질 적 인 차이 가 있다.
프 록 시 모드 의 역할 은 다른 대상 에 게 이 대상 에 대한 접근 을 제어 하기 위해 프 록 시 를 제공 하 는 것 입 니 다.어떤 경우 에 한 고객 이 다른 대상 을 원 하지 않 거나 직접 인용 할 수 없 으 며 대리 대상 은
클 라 이언 트 와 목표 대상 간 에 중개 역할 을 한다.
프 록 시 모드 에서 일반적으로 언급 되 는 역할 은 다음 과 같다.
추상 적 인 역할: 실제 대상 과 대리 대상 의 공동 인 터 페 이 스 를 설명 합 니 다.
대리 역할: 대리 대상 역할 내부 에 실제 대상 에 대한 인용 이 포함 되 어 있어 실제 대상 을 조작 할 수 있 고 대리 대상 은 실제 대상 과 같은 인 터 페 이 스 를 제공 하여 언제든지 진실 을 대체 할 수 있 습 니 다.
대상또한 대리 대상 은 실제 대상 조작 을 수행 할 때 다른 조작 을 추가 할 수 있어 실제 대상 을 봉인 하 는 것 과 같다.
실제 역할: 대리 역할 이 대표 하 는 진실 한 대상 은 우리 가 최종 적 으로 인용 해 야 할 대상 이다.
정적 에이전트
정적 에이전트 와 피 에이전트 대상 은 에이전트 전에 확 정 됩 니 다.그들 은 모두 같은 인 터 페 이 스 를 실현 하거나 같은 추상 류 를 계승 한다.
/**
 *     
 */
public abstract class Subject {
    abstract public void request();
}
 
/**
 *     :   Subject request()  
 */
public class RealSubject extends Subject {
 
    public RealSubject() {
    }
 
    public void request() {
        System.out.println("         RealSubject.request()   !");
    }
}
 
 
/**
 *     
 */
public class ProxySubject extends Subject {
    private RealSubject realSubject; //               
 
    public ProxySubject() {
    }
 
    //            request  
    public void request() {
        preRequest();               //        
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();     //          request  
        postRequest();              //        
    }
 
    private void preRequest() {
        // something you want to do before requesting
        System.out.println("        ProxySubject.preRequest()!");
    }
 
    private void postRequest() {
        // something you want to do after requesting
        System.out.println("        ProxySubject.postRequest()!");
    }
}
 
/**
 *      
 */
public class Client {
    public static void main(String[] args) {
        Subject sub = new ProxySubject();
        sub.request();
    }
}

클 라 이언 트 호출 을 실행 합 니 다. 결 과 는 다음 과 같 습 니 다.
 
프 록 시 전에 실 행 된 작업 Proxy Subject. preRequest ()!
실제 캐릭터 요청 방법 RealSubject. request () 호출 됨!
프 록 시 후 실 행 된 작업 Proxy Subject. postRequest ()!
코드 내용 은 매우 간단 합 니 다. 상기 코드 를 통 해 알 수 있 듯 이 고객 이 실제 호출 해 야 하 는 것 은 RealSubject 류 의 request () 방법 입 니 다. 현 재 는 Proxy Subject 로 RealSubject 류 를 대리 하고 똑 같이 목적 을 달성 하 는 동시에 다른 방법 (preRequest (), post Request () 도 패키지 하여 다른 문 제 를 처리 할 수 있 습 니 다.  또한 상기 방법 에 따라 대리 모델 을 사용 하려 면 실제 캐릭터 는 사전에 존재 하고 이 를 대리 대상 의 내부 속성 으로 해 야 한다.그러나 실제 사용 할 때 진실 한 역할 은 반드시 대리 역할 에 대응 해 야 한다. 만약 에 대량으로 사용 하면 급 격 히 팽창 할 수 있다.또 실제 캐릭터 를 사전에 몰 랐 다 면 대 리 를 어떻게 사용 해 야 할 까?이 문 제 는 자바 의 동적 에이전트 류 를 통 해 해결 할 수 있다.아래 의 동적 에이전트 모드 를 보십시오.
동적 에이전트
자바 동적 프 록 시 클래스 는 자바. lang. reflect 패키지 에 위치 하고 보통 다음 과 같은 두 가지 종류 와 관련된다.  (1) Interface Invocation Handler: 이 인터페이스 에서 하나의 방법 만 정 의 했 습 니 다. Public object invoke (Object obj, Method method, Object [] args) 가 실제 사용 할 때 첫 번 째 매개 변 수 는 일반적으로 프 록 시 클래스 를 말 합 니 다. method 는 프 록 시 방법 입 니 다. 예 를 들 어 상기 request (), args 는 이 방법의 매개 변수 배열 입 니 다.이 추상 적 인 방법 은 대리 류 에서 동태 적 으로 실현 된다.  (2) Proxy: 이 종 류 는 동적 프 록 시 클래스 로 상례 의 Proxy Subject 와 유사 한 역할 을 합 니 다. 그 중에서 다음 과 같은 내용 의 동적 프 록 시 클래스 proctected Proxy (Invocation Handler h): 구조 함수 로 내부 의 h 할당 에 사 용 됩 니 다.  static Class getProxyClass (ClassLoader loader, Class [] interfaces): 하나의 프 록 시 클래스 를 얻 었 습 니 다. 그 중에서 loader 는 클래스 로 더 이 고 interfaces 는 실제 클래스 가 가지 고 있 는 모든 인터페이스의 배열 입 니 다.  static Object newProxyInstance (ClassLoader loader, Class [] interfaces, InvocationHandler h): 프 록 시 클래스 의 인 스 턴 스 를 되 돌려 줍 니 다. 되 돌아 온 프 록 시 클래스 는 프 록 시 클래스 로 사용 할 수 있 습 니 다 (피 프 록 시 클래스 가 Subject 인터페이스 에서 설명 한 방법 을 사용 할 수 있 습 니 다) 동적 프 록 시 클래스  Dynamic Proxy 란 이러한 class 입 니 다. 실행 할 때 생 성 된 class 입 니 다. 생 성 할 때 interface 를 제공 해 야 합 니 다. 그리고 이 class 는 이러한 interface 를 실현 했다 고 주장 합 니 다.너 는 당연히 이 class 의 인 스 턴 스 를 이 interface 의 어떤 것 으로 도 사용 할 수 있다.물론 이 Dynamic Proxy 는 프 록 시 입 니 다. 실질 적 인 작업 을 대신 하지 않 습 니 다. 인 스 턴 스 를 생 성 할 때 handler 를 제공 하여 실제 작업 을 인수 해 야 합 니 다.  동적 에이전트 클래스 를 사용 할 때, 우 리 는 InvocationHandler 인 터 페 이 스 를 실현 해 야 한다.  다음 예 를 들 어 정적 대 리 를 바탕 으로 동적 에이전트 로 바 꿉 니 다.
/**
 *     
 */
public interface Subject {
    public void request();
}
 
/**
 *     :    
 */
public class RealSubject implements Subject {
    public RealSubject() {
    }
 
    public void request() {
        System.out.println("         RealSubject.request()   !");
    }
}
 
 
/**
 *      
 *
 *           Object ,              DynamicSubject(Object obj)    ;
 *   ,       invoke  ,      method.invoke(sub,args);
 *                     ,    sub         ,
 * args                 。
 *        ,                    
 */
 
public class DynamicSubject implements InvocationHandler {
    private Object sub;       //     
 
    public DynamicSubject() {
    }
 
    /**
     *     ,         
     * @param obj        
     */
    public DynamicSubject(Object obj) {
        sub = obj;
    }
 
    /**
     *
     * @param proxy      
     * @param method       
     * @param args                 
     * @return                   。
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("        !");
        method.invoke(sub, args);
        System.out.println("        !");
        return null;
    }
}
 
 
/**
 *    
 */
public class Client {
    static public void main(String[] args) throws Throwable {
 
        RealSubject rs = new RealSubject();     //          
        //                 
        InvocationHandler dynamicSubject = new DynamicSubject(rs);
        Class<?> cls = rs.getClass();
 
        //              :
        //               ,                      。
        Subject subject = (Subject) Proxy.newProxyInstance(
                cls.getClassLoader(),           //          
                cls.getInterfaces(),            //           
                dynamicSubject);                //             :InvocationHandler  
 
        subject.request();      //           
    }
}

실행 결과:
 
대리 전에 실 행 된 작업!
구체 적 인 캐릭터 요청 방법 RealSubject. request () 가 호출 되 었 습 니 다!
대리 후 실행 되 는 동작!
요약 하면 동적 에이전트 가 실현 하 는 절차 1. 인터페이스 Invocation Handler 를 실현 하 는 클래스 를 만 들 려 면 invoke 방법 을 실현 해 야 합 니 다.
2. 프 록 시 클래스 와 인 터 페 이 스 를 만 듭 니 다.
3. 프 록 시의 정적 방법 을 통 해.
new Proxy Instance (ClassLoader loader, Class [] interfaces, Invocation Handler h) 에서 프 록 시 클래스 를 만 듭 니 다.
4. 대리 호출 방법 을 통 해.

좋은 웹페이지 즐겨찾기