소프트웨어 개발/Design Pattern

⑥ 디자인 패턴(Design Pattern) - State

늘근이 2015. 8. 16. 11:00

State 디자인 패턴도 마찬가지이지만 많은 디자인 패턴들은  나중에 변화가 생겼을때 코딩을 최소로 하고 갈아낄수 있게끔 만드는 것이다. 이로인해 추상화레벨은 올라가며 직관성은 조금 떨어지지고 이해하기가 조금 힘들지만, 한번 이해하고 나면 머리굴릴필요가 없다.

 


 


중요한것은 갈아낀다는 것에 중점을 맞추면 된다. 만약 State를 쓰지않고 단순한 상태 플래그를 가져가서 if else구문만을 이용해서 프로그램을 작성한다면, 나중에 프로그램이 수정될 경우 기존의 소스코드를 수정해야하기 때문에 어느정도 위험성이 있는것은 사실이다.

 

만약에 Context를 이용해서 그 대상이 되는 객체만 바꿔준다면, 기존의 소스코드를 수정할 필요 없이 객체만 바꿔주면 된다. 물론 뒷단의 프로그램에 영향이 있는지 없는지는 재확인해야 하는 문제이기는 하다. 다만 달라져야 하는 부분이 그다지 일관성이 없게 설계되어있으면 if else형태로 수정하는 편이 낫다는 생각이다.


Context 클래스 (state를 받고 설정하는 부분이며, 그 state에서 사용할 메서드또한 설정한다.)

 
public class Context implements State{
	
	private State currentState;
	
	public void setState(State state) {
		this.currentState = state;
	}
	
	public State getState() {
		return this.currentState;
	}
	@Override
	public void go() {
		this.currentState.go();
	}


}


State 인터페이스 (Context가 결론적으로 이용할 메서드를 선언)

 
public interface State {
	public void go();
}


ConcreteStateA (State 구현부)

 
public class ConcreteStateA implements State {

	@Override
	public void go() {
		// TODO Auto-generated method stub
		System.out.println("go - 1");
	}

}



ConcreteStateB (State 구현부)

 
public class ConcreteStateB implements State {

	@Override
	public void go() {
		// TODO Auto-generated method stub
		System.out.println("go - 2");
	}

}


Main 메인프로그램 부분

 
public class Main {
	public static void main(String[] args) {
		Context context = new Context();
		
		State stateA = new ConcreteStateA();
		State stateB = new ConcreteStateB();
		
		context.setState(stateA);
		context.go();
		
		context.setState(stateB);
		context.go();
		
	}
}



결과는 다음과 같다.

go - 1
go - 2



예를들어 인터넷 서점에서 회원의 등급별로 마일리지를 주어야하는 것이 점수가 아닌 세부적인 내부 계산로직이 달라져야 한다면 위와같이 State패턴을 가지고 갈아끼면서 작동하게 만들수 있겠다.