상세 컨텐츠

본문 제목

분류 코드를 상태/전략 패턴으로 치환

자바강좌/리팩토링

by somiyuralove 2020. 2. 8. 13:30

본문

* 분류 코드를 상태/전략 패턴으로 치환
- 분류코드(type code)는 객체 종류를 나타내는 값. 분류코드를 상태/전략 패턴으로 치환(Replace Type Code with State/Strategy) 리팩토링에서
상태패턴 또는 전략패턴이라는 디자인패턴을 사용함.
- 분류 코드를 상태/전략 패턴으로 치환은 분류 코드를 상태 객체라고 부르는 객체를 사용해 치환함.

* 방법

1. 상태 객체를 나타내는 클래스 작성
- 분류 코드를 자기 캡슐화
- 분류 코드를 나태내는 새로운 클래스(상태 클래스) 작성
- 분류 코드를 값마다 상태 객체의 하위 클래스 작성
- 분류 코드를 얻는 추상 메서드를 상태 객체에 작성
- 하위 클래스는 추상 메서드를 오버라이드해서 분류 코드를 변환
- 컴파일

2. 상태 객체 사용
- 분류 코드를 사용하는 클래스에 상태 객체용 필드 추가
- 분류 코드를 조사하는 코드를 분류 코드를 얻는 메서드 호출로 치환
- 분류 코드를 변경하는 코드를 상태 객체를 변경하는 코드로 치환
- 컴파일해서 테스트

* 리팩토링 전 코드

package ReplaceTypeCodeWithStateStrategy.before;

public class Logger {
public static final int STATE_STOPPED = 0;
public static final int STATE_LOGGING = 1;
private int _state;
public Logger() {
_state = STATE_STOPPED;
}
public void start() {
switch(_state) {
case STATE_STOPPED:
System.out.println("** START LOGGING **");
_state = STATE_LOGGING;
break;
case STATE_LOGGING:
break;
default:
System.out.println("Invalid state: " + _state);
}
}

public void stop() {
switch(_state) {
case STATE_STOPPED:
break;
case STATE_LOGGING:
System.out.println("** STOP LOGGING **");
_state = STATE_STOPPED;
break;
default:
System.out.println("Invalid state: " + _state);
}
}

public void log(String info) {
switch (_state) {
case STATE_STOPPED:
System.out.println("Ignoring: " + info);
break;
case STATE_LOGGING:
System.out.println("Logging: " + info);
break;
default:
System.out.println("Invalid state: " + _state);
}

}
}


package ReplaceTypeCodeWithStateStrategy.before;

public class Main {
public static void main(String[] args) {
Logger logger = new Logger();
logger.log("information #1");

logger.start();
logger.log("information #2");

logger.start();
logger.log("information #3");

logger.stop();
logger.log("information #4");

logger.stop();
logger.log("information #5");
}
}

* 리팩토링 후 코드

package ReplaceTypeCodeWithStateStrategy.after.copy;

public class Logger {
public static final int STATE_STOPPED = 0;
public static final int STATE_LOGGING = 1;
// private int _state;
private State _state;

public Logger() {
// _state = STATE_STOPPED;
setState(STATE_STOPPED);
}
public void start() {
switch(getState()) {
case STATE_STOPPED:
System.out.println("** START LOGGING **");
// _state = STATE_LOGGING;
setState(STATE_LOGGING);
break;
case STATE_LOGGING:
break;
default:
// System.out.println("Invalid state: " + _state);
System.out.println("Invalid state: " + getState());
}
}

public void stop() {
switch(getState()) {
case STATE_STOPPED:
break;
case STATE_LOGGING:
System.out.println("** STOP LOGGING **");
setState(STATE_STOPPED);
break;
default:
System.out.println("Invalid state: " + getState());
}
}

public void log(String info) {
switch (getState()) {
case STATE_STOPPED:
System.out.println("Ignoring: " + info);
break;
case STATE_LOGGING:
System.out.println("Logging: " + info);
break;
default:
System.out.println("Invalid state: " + getState());
}

}

public int getState() {
return _state.getTypeCode();
}

public void setState(int state) {
switch(state) {
case STATE_STOPPED:
_state = new StateStopped();
break;
case STATE_LOGGING:
_state = new StateLogging();
break;
default:
System.out.println("Invalid state: " + state);
}

}
}

package ReplaceTypeCodeWithStateStrategy.after.copy;

public class Main {
public static void main(String[] args) {
Logger logger = new Logger();
logger.log("information #1");

logger.start();
logger.log("information #2");

logger.start();
logger.log("information #3");

logger.stop();
logger.log("information #4");

logger.stop();
logger.log("information #5");
}
}


package ReplaceTypeCodeWithStateStrategy.after.copy;

public abstract class State {
public abstract int getTypeCode();
}


package ReplaceTypeCodeWithStateStrategy.after.copy;

public class StateLogging extends State{

@Override
public int getTypeCode() {
// TODO Auto-generated method stub
return Logger.STATE_LOGGING;
}
}

package ReplaceTypeCodeWithStateStrategy.after.copy;

public class StateStopped extends State{

@Override
public int getTypeCode() {
// TODO Auto-generated method stub
return Logger.STATE_STOPPED;
}

}



관련글 더보기

댓글 영역