Proxy Pattern (프록시 패턴)

Proxy Pattern


 

프록시


1.    원격프록시 : 원격객체에 대한 접근을 제어


2.    가상프록시 : 생성하기 힘든 자원(ex. Image)에 대한 접근을 제어


3.    보호프록시 : 접근권한이 필요한 자원에 대한 접근을 제어


 

사용 목적


실제 객체의 생성시간이 오래걸리는 경우 일을 분업하여 간단한 초기 작업을 프록시에서 하고


가장 중요한 마지막 작업에서 프록시객체는 실제 객체를 생성하고 위임한다.


 

특징


1.    프록시는 실제 서비스와 같은 이름의 메소드를 인터페이스를 사용하여 구현한다.


2.    프록시는 실제 서비스에 대한 참조 변수를 갖는다.


3.    대리자는 실제 서비스의 같은 이름을 가진 메소드를 호출하고 그 값을 클라이언트에게 돌려준다.


4.    대리자는 실제 서비스의 메소드 호출 전후에도 별도의 로직을 수행할 수 있다.



 

원격프록시


로컬 환경에 존재하며, 원격객체(JVM Heap에 있는 객체)에 대한 대변자 역할을 하는 객체


서로 다른 주소 공간에 있는 객체에 대해 마치 같은 주소 공간에 있는 것처럼 동작하게 만드는 패턴


 

가상프록시


꼭 필요로 하는 시점까지 객체의 생성을연기하고, 해당 객체가 생성된 것처럼 동작하도록 만들고 싶을 때 사용하는 패턴


 

보호프록시


객체에 대한 접근 권한을 제어하거나 객체마다 접근 권한을 달리하고 싶을 때 사용하는 패턴으로 


실객체에 대한 접근을 가로채어 중간에서 권한 점검을 수행


 

소스코드


인터페이스

public interface Image {
   
void display();
}

 

프록시

public class ProxyImage implements Image {
   
private RealImage realImage;
   
private String fileName;

   
public ProxyImage(String fileName){
       
this.fileName=fileName;
    }

   
@Override
    public void
display() {
       
if(realImage == null){
           
realImage = new RealImage(fileName);
        }
       
realImage.display();
    }
}

 

실제

public class RealImage implements Image {

   
private String fileName;

   
public RealImage(String fileName){
       
this.fileName=fileName;
       
loadFromDisk(fileName);
    }
   
private void loadFromDisk(String fileName){
       
System.out.println("Loading " + fileName);
    }
   
@Override
    public void
display() {
       
System.out.println("Displaying " + fileName);
    }
}

 

메인

public class Main {
   
public static void main(String[] args){
       
Image image = new ProxyImage("test.jpg");
       
image.display();
    }
}



결과화면




UML



State Pattern (스테이트 패턴)

State Pattern

 


정의


Object의 내부 상태가 바뀜에 따라서 object의 행동을 바꿀 수 있다.


마치 object class가 바뀌는 것과 같은 결과를 얻을 수 있다.


State patternstateclass로 표현한다


그 이유는, class의 교체를 통해서 state의 변화를 나타낼 수 있고, 새로운 state를 추가해야 할 때, 편리하기 때문이다.

 


적용 영역


1.    Object의 행위가 object state에 의존하고 그 object의 행위가 실행 시점에서 object state에 따라 변화해야 할 경우


2.    Operation이 크고, objectstate에 따라 다수의 조건문을 포함하는 경우


 

State vs Strategy (pattern)


State pattern을 사용할 때는 state object의 행동이 캡슐화 된다


State에 따라 context object에서 여러 state object 중 한 object에게 모든 행동을 위임한다.


해당 object의 내부 state에 따라 현재 state를 나타내는 object가 바뀌고


그 결과 context object의 행동도 바뀐다. Clientstate object에 대해서 몰라도 된다.


하지만, strategy patternclient에서 context object한테 어떤 object를 사용할지 정한다


Strategy pattern은 주로 실행시에 전략 object를 변경할 수 있는 유연성을 제공하기 위한 용도로 쓰이며, 가장 적합한 전략 object를 선택해서 사용한다.


, strategy pattern은 외부에서 상황에 맞게 변화를 줄 수 있고, state pattern은 자신이 직접 상태변화에 관여한다는 것이다



구성요소


1.    State를 나타내는 state


2.    state간의 전의를 표현하는 action


3.    state 전이에 나타나는 onEntry, onExit 함수


 

소스코드


Action(enum)

public enum Action {
   
EAT, DIGEST, GOTOBED;
}

 

State(enum)

public enum State {
   
HUNGRY{
       
public State act(Action action){
           
switch (action){
                
case EAT: return FULL;
               
default: return null;
            }
        }
    },
   
FULL{
       
public State act(Action action){
           
switch (action){
               
case EAT: return ANGRY;
               
case DIGEST: return HUNGRY;
               
case GOTOBED: return SLEEPING;
               
default: return null;
            }
        }
    },
   
ANGRY{
       
public State act(Action action){
           
switch (action){
               
case DIGEST: return FULL;
                
default: return null;
            }
        }
    },
   
SLEEPING{
       
public void onEntry(){
           
System.out.println("go bed");
        }
       
public State act(Action action){
           
return null;
        }
    };
   
abstract State act(Action action);
   
public static State getInitState(){
       
return HUNGRY;
    }
   
public static boolean isFinalState(State state){
       
return state==SLEEPING;
    }
   
public void onEntry(){}
   
public void onExit(){}
}

 

StateContext(class)

public class StateContext {
   
private State currentState;
   
public StateContext(){
       
currentState = State.getInitState();
    }
   
public void processEvent(Action action){
       
State next= currentState.act(action);
       
if(next != null){
            
currentState.onExit();
           
System.out.println(action +"에 의해 State " +
                   
currentState+"에서 "+next+"로 바뀜");
           
currentState=next;
           
currentState.onEntry();
           
if(State.isFinalState(currentState)){
               
System.out.println("i'm final State");
            }
        }
else{
           
System.out.println(action+" state " +currentState
           
+"에서는 의미 없는 짓");
        }
    }
}

 

Main

public class Main {
   
public static void main(String[] args){
       
StateContext context = new StateContext();
       
context.processEvent(Action.EAT);
       
context.processEvent(Action.EAT);
       
context.processEvent(Action.GOTOBED);
       
context.processEvent(Action.DIGEST);
       
context.processEvent(Action.EAT);
       
context.processEvent(Action.GOTOBED);
       
context.processEvent(Action.DIGEST);
       
context.processEvent(Action.GOTOBED);
    }
}



결과




UML



'SW'에 해당되는 글 2건

1 →