2015년 9월 21일 월요일

클래스 디자인 패턴 11. proxy pattern_

1. 개념잡기
  1) 의미 및 구현방법
      현재 상태를 다른 프로그램에서 요청하여 볼 수 있도록
        하는 기능입니다.
      다른 프로그램을 엿보기 위해서 클라이언트(요청하는곳) 과
        서비스(요청에 대한 응답) 기능을 두고 그 사이에 통신 기능을
        넣어서 서로 정보를 주고 받을 수 있도록 해야 합니다.
        이를 위해서 통신 기능을 넣어야 하지만
         java의 RMI 클래스를 통해서
        이를 쉽게 프록시로 생성하여 관리 가능합니다.

관련 클래스
java.rmi.Remote : interface
import java.rmi.RemoteException : class 오류 관리



  2) 참고자료
      RMI 클래스는
     http://www.javadom.com/tutorial/rmi-idl/

     http://java.ihoney.pe.kr/54


2. 소스
 소스는 기본적으로 디자인 패턴 10번을 가지고 진행합니다.

  1) rmi.Remote를 상속받아서 interface를 구현

 
package instances;

import java.rmi.Remote;
import java.rmi.RemoteException;

import stateI.State;

public interface GumballMachineRemote extends Remote {
    public int getCount() throws RemoteException;
    public String getLocation() throws RemoteException;
    public State getState() throws RemoteException;
}


  2) GumballMachine 은 rmi.server 의 UnicastRemoteObject를
      상속받도록 수정한다.
 
public class GumballMachine extends UnicastRemoteObject implements GumballMachineRemote {

 State soldOutState;
 State noQuarterState;
 State hasQuarterState;
 State soldState;
 
 State state = soldOutState;
 
 int count =0;
 
 public GumballMachine(String locatrion, int numberGumballs) throws RemoteException {
  soldOutState = new SoldOutState(this);
  noQuarterState = new NoQuarterState(this);
  hasQuarterState = new HasQuarterState(this);
  soldState = new SoldState(this);
  
  this.count =numberGumballs;
  
  if(numberGumballs>0){
   state = noQuarterState;
  }
 }


  3) State 객체는 직렬화가 가능토록 직렬화 상속을 받아서
      진행한다.
 
package stateI;

import java.io.Serializable;

public interface State extends Serializable {
 public void insertQuarter();
 public void ejectQuarter();
 public void turnCrank();
 public void dispense();
} 


  4) 기존 testDrive 는 아래와 같이 처리한다.
 
package tsstmain;

import java.rmi.Naming;

import instances.GumballMachine;
import instances.GumballMachineRemote;

public class GumballMachineTestDrive {
 public static void main(String[] args) {
  GumballMachineRemote gumballMachine = null;
  int count;

  if (args.length < 2) {
   System.out.println("GumballMachine  ");
   System.exit(1);
  }

  try {
   count = Integer.parseInt(args[1]);
   gumballMachine = new GumballMachine(args[0], count);
   Naming.rebind("//" + args[0] + "/gumballmachine", gumballMachine);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
} 


  5) GumballMonitor에 예외처리를 해준다.

 
package instances;

import java.rmi.*;

public class GumballMonitor {
    GumballMachineRemote machine;
   
    public GumballMonitor(GumballMachineRemote machine) {
        this.machine = machine;
    }

    public void report() {
        try{
            System.out.println("뽑기 기계위치:"+machine.getLocation());
            System.out.println("현재 재고:"+machine.getCount()+" 개");
            System.out.println("현재 상태:"+machine.getState());
        } catch(RemoteException e){
            e.printStackTrace();
        }
    }
}


  6) GumballMonitorTestDrive  를 구현하여 요청하는 client 단의
      내용을 test 할 수 있도록 한다.

package instances;

import java.rmi.Naming;

public class GumballMonitorTestDrive {
 public static void main(String[] args) {
  String[] location = {"rmi://santafe.mightygumball.com/gumballmachine","rmi://boulder.mightygumball.com/gumballmachine","rmi://seattle.mightygumball.com/gumballmachine"};
  GumballMonitor[] monitor = new GumballMonitor[location.length];
 
  for(int i=0; i<location.length;i++){
   GumballMachineRemote machine;
   try {
    machine = (GumballMachineRemote) Naming.lookup(location[i]);
    monitor[i] = new GumballMonitor(machine);
    System.out.println(monitor[i]);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
   for(int i=0; i<monitor.length;i++){
   
   }
 }
}


  7) 이를 테스트 하려면 rmi Registry 플러그인이 필요하다.
      하단 링크 참고
http://blog.bagesoft.com/646
결과 : 실행순서 :     (1) rmiRegistry .....           (2) GumballMachineTestDrive          이걸 실행시 인자 값을 줘야함 String   int         java GumballMachineTestDrive seattle.mightygumball.com 100         java GumballMachineTestDrive boulder.mightygumball.com 100        run - configration 에서 Argument 부분에서 인자값을 넣어줘야 함. .....     (3) GumballMonitorTestDrive
%java GumballMonitorTestDrive
뽑기 기계 위치 : seattle.mightygumball.com
현재 재고 : 100 개
현재 상태 : 동전 투입 대기중

2. 다이어그램

  3) 다이어그램
      역시 하단 링크를 참고바랍니다.
      하단 링크에서도 자세하게 설명하고 있습니다.
      state 및 이를 implements 한 구현체 클래스는 스트리티지
      패턴과 비슷하나 이를 밖에서 조합하여
      쓰는 과정에서 약간 차이가 있음.

   http://secretroute.tistory.com/entry/Head-First-Design-Patterns-%EC%A0%9C11%EC%9E%A5-Proxy-%ED%8C%A8%ED%84%B4-1

댓글 없음:

댓글 쓰기