Android 디자인 모드 의 프 록 시 모드 Proxy 알 기 쉬 운 상세 설명

개술
대리 모델 도 평소에 자주 사용 하 는 디자인 모델 중 하나 이다.대리 모델 은 바로 새로운 대상 을 제공 하여 실제 대상 에 대한 조작 을 실현 하거나 실제 대상 의 대역 이 되 는 것 이다.일상생활 에서 도 흔히 볼 수 있다.예 를 들 어 A 는 집 을 빌려 야 한다.번 거 로 움 을 줄 이기 위해 A 는 중 개 를 찾 아 간다.중 개 는 A 를 대신 해서 집 을 선별 하고 A 는 앉 아서 중 개 를 선별 한 결과 이다.또한 방 세 를 내 는 것 도 중개 에 게 맡 기 는 것 이다.이것 은 전형 적 인 일상생활 에서 대리 모델 의 응용 이다.평소에 웹 페이지 를 열 면 가장 먼저 열 리 는 것 은 보통 문자 이 고 그림 등 큰 자원 은 로드 가 지연 되 며 여기 서도 대리 모델 을 사용 했다.
에이전트 모드 구성
Abstract Subject:추상 적 인 주제-실제 주제 와 프 록 시 주제 의 공 통 된 인 터 페 이 스 를 설명 합 니 다.
Real Subject:리 얼 테마-리 얼 대상,프 록 시 테마 참조 필요
Proxy Subject:프 록 시 테마-Proxy Subject 가 RealSubject 를 인용 하고 RealSubject 와 같은 인 터 페 이 스 를 실현 하기 때문에 Proxy Subject 는 RealSubject 를 조작 할 수 있 고 추가 작업 도 제공 할 수 있 습 니 다.예 를 들 어 before&after

프 록 시 모드 는 장면 에 기반 한 분 류 를 자주 사용 합 니 다.
1.Virtual Proxy:
가상 프 록 시 는 프 록 시 모드 를 통 해 자원 을 소모 하 는 대상 에 게 로드 지연 을 하 는 것 입 니 다.바로 이 대상 을 언제 사용 해 야 만 들 수 있 습 니까?
2.Remote Proxy:원 격 프 록 시 는 비교적 전형 적 인 응용 으로 C/S 모드(주로 원 격 방법의 호출 을 차단 하고 제어 하 며 프 록 시 방화벽 등)와 유사 합 니 다.
3.Smart Reference Proxy:스마트 참조 대 리 는 인 용 된 대상 에 게 내부 중개 Searching 과 Prepare contract 를 실현 하 는 동작 등 추가 적 인 조작 을 제공 할 수 있 습 니 다.
4.Access Proxy;보호 에이 전 트 는 대상 의 접근 을 제어 할 수 있 으 며 필요 할 때 일련의 권한 관 리 를 제공 합 니 다.
5.Copy-on-write Proxy:쓰기 시 복사(복제)대 리 는 사실 Virtual Proxy 의 갈래 입 니 다.큰 대상 을 복사 할 때 대상 이 진정 으로 변 한 후에 만 복사(복제)작업 을 할 수 있 습 니 다(복사 지연).
프 록 시 모드 의 장단 점:
장점:
1.프 록 시 는 실제 대상 과 의 중간 층 으로 호출 되 어 모듈 간 과 시스템 의 결합 성 을 낮 춘 다.
2.작은 대상 으로 큰 대상 을 대리 하여 시스템 의 운행 속 도 를 최적화 하 는 목적 을 달성 할 수 있다.
3.RealSubject 의 권한 관리 제공
4.확장 이 용이 합 니 다.RealSubject 와 Proxy Subject 가 모두 인터페이스 화 되 었 습 니 다.RealSubject 가 업 무 를 변경 한 후에 인터페이스 가 변 하지 않 으 면 Proxy Subject 는 아무런 수정 도 하지 않 을 수 있 습 니 다.
단점:
1.같은 장점 1.호출 자 와 실제 대상 이 중간 층 이 많아 서 호출 응답 시간 이 증가 합 니 다.
실현
여 기 는 A 를 가지 고 중개 임대 주택 을 찾 아 데모 로 대리 모델 을 구축 합 니 다.
1.일반 에이전트
장면 에 따라 추상 적 인 주 제 를 정의 하고 IHouse 는 세 가지 방법 을 제공 하 는데 그것 이 바로 주택 정 보 를 얻 고 계약 을 체결 하 며 임대 료 를 지불 하 는 것 이다.

/** 
 * Created by jesse on 15-7-24. 
 */ 
public interface IHouse { 
  void getHouseInfo(); 
  void signContract(); 
  void payFees(); 
} 
다음은 실제 주 제 를 정의 하고 IHouse 인 터 페 이 스 를 실현 합 니 다.집의 이름과 가격 두 가지 속성 을 증가 하고 핑계 방법 을 채 우 며 집 정 보 를 얻 을 때 집의 이름과 가격 을 로그 합 니 다.계약 을 할 때 log 는 계약 시간 을 내 고 임대 료 를 낼 때 log 는 가격 을 낸다.

public class House implements IHouse{ 
  private final String TAG = House.class.getSimpleName(); 
  private String name; 
  private double price; 
 
  public House(String name, double price){ 
    this.name = name; 
    this.price = price; 
  } 
 
  @Override 
  public void getHouseInfo() { 
    Log.i(TAG, "House Info- name:" + name + " ¥:" + price); 
  } 
 
  @Override 
  public void signContract() { 
    Log.i(TAG, "Contract:" + name + " signed at" + 
        new SimpleDateFormat("HH:mm:ss").format(SystemClock.uptimeMillis())); 
  } 
 
  @Override 
  public void payFees() { 
    Log.i(TAG, "Bill: name-" + name + " $-" + price); 
  } 
} 
주택 대 리 를 정의 하 는 것 도 IHouse 인 터 페 이 스 를 실현 하고 House 의 인용 을 가 져 야 한다.대리 류 는 마치 패키지 하우스 가 있 는 것 처럼 부가 적 인 조작 을 제공 하 는 것 을 볼 수 있다.예 를 들 어 고객 이 집 을 보 려 고 할 때 대 리 는 자신의 재고 주택 정 보 를 먼저 검색 하고 계약 을 체결 하기 전에 계약 을 준비 해 야 한다.

public class ProxyHouse implements IHouse{ 
  private final String TAG = ProxyHouse.class.getSimpleName(); 
  private IHouse house; 
  public ProxyHouse(IHouse house){ 
    this.house = house; 
  } 
  @Override 
  public void getHouseInfo() { 
    Log.i(TAG, "searching"); 
    house.getHouseInfo(); 
    Log.i(TAG, "search finished"); 
  } 
 
  @Override 
  public void signContract() { 
    Log.i(TAG, "prepare contract"); 
    house.signContract(); 
  } 
 
  @Override 
  public void payFees() { 
    house.payFees(); 
  } 
} 
고객 에 게 있어 House 와 직접적인 상호작용 을 하지 않 아 도 된다.여기 서 먼저 당 돈 장원 이 라 고 정의 하고 임대료 5k 를 내 며 주택 대 리 를 설립 하여 당 돈 장원 을 대리 에 게 위탁 한다.고객 은 집 을 찾 고 계약 을 체결 하 며 임대 료 를 내 고 직접 대 리 를 찾 으 면 된다.

IHouse house = new House("Downton Abbey", 5000); 
IHouse proxyHouse = new ProxyHouse(house); 
Log.i(TAG, "looking for a perfect house"); 
proxyHouse.getHouseInfo(); 
Log.i(TAG, "thinking"); 
proxyHouse.signContract(); 
proxyHouse.payFees(); 
Log.i(TAG, "so easy");

전체 프 록 시 모드 의 절 차 는 아래 의 순서 그림 에서 보 여 줍 니 다.client 는 프 록 시 와 만 상호작용 을 합 니 다.

2.가상 에이전트
가상 에이전트 앞 에 소개 되 어 있 습 니 다.프 록 시 모드 를 바탕 으로 로드 지연 을 해서 메모 리 를 절약 하 는 것 입 니 다.그러나 특정한 대상 이 고정된 순서 가 없 는 여러 곳 에서 사용 하려 면 빈 칸 을 판단 하고 어느 정도 성능 을 희생 합 니 다(약간 프 록 시 모드+게으름뱅이 모드 와 같 습 니 다).여 기 는 전세 의 예 를 들 어 보 여 줍 니 다.
하우스 가 엄 청 난 대상 이 라 고 가정 하고 만 들 때 자원 을 많이 소모 한다 면 우 리 는 Custom 이 그것 을 사용 해 야 할 때 초기 화 하 는 것 으로 바 꿉 니 다.여기 서 프 록 시 하우스 구 조 를 만 들 때 하우스 의 인용 이 비어 있 는 지 여 부 를 먼저 판단 한 다음 에 하우스 가 초기 화 됩 니 다.물론 이곳 에 다 중 스 레 드 가 병발 한다 면 서로 다른 장면 에 따라 자 물 쇠 를 추가 하거나 더 블 자 물 쇠 를 검사 하여 스 레 드 안전 을 확보 할 수 있 습 니 다.

public ProxyHouse(){ 
  if (null == house) 
    house = new House("Downton Abbey", 5000); 
} 
[java] view plain copy
IHouse proxyHouse = new ProxyHouse(); 
Log.i(TAG, "looking for a perfect house"); 
proxyHouse.getHouseInfo(); 
Log.i(TAG, "thinking"); 
proxyHouse.signContract(); 
proxyHouse.payFees(); 
Log.i(TAG, "so easy"); 
3.강제 대리
강제 대 리 는 반대로 하 는 대리 모델 이다.일반적인 상황 에서 대리 모델 은 대 리 를 통 해 진실 한 대상 을 찾 고 강제 대 리 는 진실 한 대상 을 통 해 대 리 를 찾 을 수 있다.즉,실제 대상 이 대 리 를 지정 하 는 것 이다.물론 최종 방문 은 대리 모델 을 통 해 방문 하 는 것 이다.이름 에서 다른 대리 와 다르다 는 것 을 알 수 있다.바로 대 리 를 강제 하 는 것 입 니 다.위의 일반 대 리 를 예 로 들 면 Custom 은 실체 가 보이 지 않 는 House 를 대리 로 만 방문 할 수 있 습 니 다.그러나 제한 이 없 기 때문에 Custom 은 Proxy House 를 돌아 서 House 를 방문 할 수 있 습 니 다.그러나 강제 대 리 는 하나의 제한 이 있 습 니 다.Custom 은 반드시 Proxy House 를 통 해 집 을 방문 해 야 합 니 다.마치 일부 집주인 들 이 귀 찮 게 하 는 것 처럼.세입 자가 직접 전 화 를 걸 어 집 을 보 겠 다 고 하 자 집주인 은 중개 에 게 전 화 를 걸 어 중개 에 게 연락 하 라 고 했다.
우선 인터페이스 에 프 록 시 를 가 져 오 는 인 터 페 이 스 를 추가 해 야 합 니 다.

public interface IHouse { 
  void getHouseInfo(); 
  void signContract(); 
  void payFees(); 
  IHouse getProxy(); 
} 
실제 대상 은 인 터 페 이 스 를 실현 하고 getProxy 에서 대 리 를 예화 하 는 동시에 다른 방법 에서 대리 판단 을 하 며 자신 이 정 한 대 리 를 사용 해 야 정상적으로 진행 할 수 있 습 니 다.

public class House implements IHouse{ 
  private final String TAG = House.class.getSimpleName(); 
  private String name; 
  private double price; 
  private IHouse proxy; 
 
  public House(String name, double price){ 
    this.name = name; 
    this.price = price; 
  } 
 
  @Override 
  public void getHouseInfo() { 
    if (isProxy()) 
      Log.i(TAG, "House Info- name:" + name + " ¥:" + price); 
    else 
      Log.i(TAG, "Please use correct proxy"); 
  } 
 
  @Override 
  public void signContract() { 
    if (isProxy()) 
      Log.i(TAG, "Contract:" + name + " signed at" + 
          new SimpleDateFormat("HH:mm:ss").format(SystemClock.uptimeMillis())); 
    else 
      Log.i(TAG, "Please use correct proxy"); 
 
  } 
 
  @Override 
  public void payFees() { 
    if (isProxy()) 
      Log.i(TAG, "Bill: name-" + name + " $-" + price); 
    else 
      Log.i(TAG, "Please use correct proxy"); 
  } 
 
  @Override 
  public IHouse getProxy() { 
    if (null == proxy) 
      proxy = new ProxyHouse(this); 
    return proxy; 
  } 
 
  private boolean isProxy(){ 
    if (null == proxy) 
      return false; 
    else 
      return true; 
  } 
} 
이때 하우스 대상 을 직접 조작 하거나 Custom 으로 구 축 된 대 리 를 통 해 방문 하면 다음 과 같은 결 과 를 되 돌려 줍 니 다.

그래서 우 리 는 실제 대상 이 지정 한 대 리 를 사용 해 야 정상적으로 접근 할 수 있 습 니 다.

IHouse house = new House("Downton Abbey", 5000); 
house = house.getProxy(); 
Log.i(TAG, "looking for a perfect house"); 
house.getHouseInfo(); 
Log.i(TAG, "thinking"); 
house.signContract(); 
house.payFees(); 
그러나 여기 강제 대리 에 bug 가 있 습 니 다.강제 대 리 는 효력 이 발생 하지 않 습 니 다.Custom 은 하 우 스 를 직접 방문 할 수 있 습 니 다.예 를 들 어 저 는 아래 의 방식 으로 방문 할 수 있 습 니 다.getProxy 를 통 해 대 리 를 만 들 고 가 져 올 뿐 저 는 대 리 를 하지 않 고 하우스 의 인 스 턴 스 로 직접 방문 할 수 있 습 니 다.이 럴 때 는 정상적으로 방문 할 수 있 습 니 다.나중에 이 버그 를 풀 고 업데이트 할 수 있 습 니 다.

IHouse house = new House("Downton Abbey", 5000); 
house.getProxy();//      getProxy      
Log.i(TAG, "looking for a perfect house"); 
house.getHouseInfo(); 
Log.i(TAG, "thinking"); 
house.signContract(); 
house.payFees(); 
4.동적 에이전트
위 에서 소개 한 것 은 모두 자신 이 먼저 쓴 대리 류 입 니 다.이렇게 대리 관 계 는 모두 고정 적 입 니 다.여러 개의 실제 대상 을 대리 할 때 여러 개의 대리 류 를 써 야 하고 불필요 한 코드 가 발생 할 수 있 습 니 다.확장 성과 유지 가능성 이 높 지 않 습 니 다.동적 에이 전 트 는 반 사 를 바탕 으로 프로그램 이 실행 되 는 과정 에서 어떤 대상 을 대리 할 지 결정 하 는 것 이다.AOP 와 같은 핵심 사상 은 바로 동적 에이 전 트 를 사용 하 는 것 이다.(여 기 는 자바 의 동적 에이 전 트 를 사용한다)
동적 에이전트 인 만큼 프 록 시 하우스 도 필요 없고 아이 하우스 인 터 페 이 스 를 실현 할 필요 가 없습니다.여기에 프 록 시 핸들 러 가 Invocation Handler 를 실현 하 는 invoke 인 터 페 이 스 를 쓰 고 프 록 시 에 따라 구 축 된 프 록 시 인 스 턴 스 를 제공 합 니 다.실제 대상 의 구체 적 인 방법 을 반사 적 으로 호출 하기 전에 이 방법의 이름 을 인쇄 합 니 다.

public class ProxyHandler implements InvocationHandler{ 
  private final String TAG = ProxyHandler.class.getSimpleName(); 
  Object targetObj; 
 
  public Object newProxyInstance(Object targetObj){ 
    this.targetObj = targetObj; 
    return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), 
          targetObj.getClass().getInterfaces(), this); 
  } 
 
  @Override 
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    Object ret; 
    Log.i(TAG, "method name:" + method.getName()); 
    ret = method.invoke(targetObj, args); 
    return ret; 
  } 
} 

ProxyHandler proxy = new ProxyHandler(); 
IHouse house = (IHouse) proxy.newProxyInstance(new House("Downton Abbey", 5000)); 
Log.i(TAG, "looking for a perfect house"); 
house.getHouseInfo(); 
Log.i(TAG, "thinking"); 
house.signContract(); 
house.payFees(); 
Log.i(TAG, "so easy"); 
결 과 를 통 해 알 수 있 듯 이 실제 invoke 의 실제 대상 방법 전에 방법 명 을 인쇄 하고 여기 서 다른 대상 통 제 를 할 수 있 습 니 다.

이때 전체 과정의 순서 도 는 아래 의 모양 으로 바 뀌 었 고 JDK 의 Proxy 대상 과 반사 체 제 를 통 해 동적 에이전트 의 핵심 기능 을 지탱 했다.

총화
프 록 시 모드 의 사용 장면 은 아직도 매우 많다.대상 의 복잡 도 를 낮 추고 프로젝트 에 대해 디 결합(특히 동적 에이전트 의 AOP)을 할 수 있다.디자인 모델 을 배 우 는 데 가장 적합 한 방법 은 바로 가 져 와 서 사용 하 는 것 이다.이 모델 에 적용 되 는 장면 에서 유연 하 게 활용 해 야 모델 을 진정 으로 파악 하 는 것 이 라 고 할 수 있다.

좋은 웹페이지 즐겨찾기