본문 바로가기

IT/개발경험기

[스테이트패턴] 스테이트패턴 적용기

안녕하세요 남갯입니다.


오늘은 디자인 패턴을 공부하던 중 스테이트 패턴을 통해 코드를 개선한 내용을 정리해보려고 합니다.


스테이트 패턴이란


스테이트패턴의 정의


스테이트 패턴을 이용하면 객체의 내부상태가 바뀜에 따라서 객체의 행동을 바꿀수 있습니다. 마치 객체의 클래스를 바뀌는것과 같은 결과를 얻을수있습니다.

* 상태를 별도의 클래스로 캡슐화하고 현재상태를 나타내는 객체한테 행동을 위임하기 때문에 내부상태가 바뀜에 따라 행동이 달라지는것을 알 수 있습니다. 



스테이트 패턴의 정의에 따라 현재 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀수 있다고 합니다.



요구사항


제가 필요했던 요구사항에서는 


자동차는 도로를 따라 일정 속도와 


1. 정체, 지연,  원할 세가지의 도로의 타입이 존재합니다.

원할 - 지연 - 정체 순으로 도로가 더 혼잡함을 의미합니다.


2. 여기서 자동차가 존재하고 자동차는 다섯가지의 의 행동을 할 수 있습니다.

1. 정지 , 2.정지 후 출발, 3. 가속, 4. 감속, 5. 속도유지


3. 해당 동작은 세가지 도로에서 지정된 순서에 맞춰 랜덤하게 발생하며, 세가지의 도로 타입에 따라 속도의 변화폭이 다릅니다.



구현



위의 필요했던 요구사항에 따라 5가지의 동작을 정의한 AbsState 클래스를 만듭니다.


abstract class AbsState {

protected SpeedGenerator speedGenerator;

protected static final int NORAML = 0;
protected static final int DESCING = 1;
protected static final int STOPPING = 2;
protected static final int ASCING = 3;
protected static final int STOP_AFTER_START = 4;

protected AbsState(SpeedGenerator speedGenerator) {
this.speedGenerator = speedGenerator;
}


5가지의 동작에 대한 행동을 하는 함수와

public void generateEventState(int descPercent, int ascPercent, int stopPercent) { //구현

protected int stopSpeed(int speed) { //구현
int smoothDescSpeed(int speed) { //구현
protected int smoothAscSpeed(int speed) { //구현
int stopAfterStart(int speed) { //구현



각 동작에 대한 큰 틀을 구성하고 



세가지 상태를 가진 도로를 구성합니다.


public class SlowlyState extends AbsState {

public SlowlyState(SpeedGenerator speedGenerator) {
super(speedGenerator);
}

public class SluggishState extends AbsState {
public SluggishState(SpeedGenerator speedGenerator) {
super(speedGenerator);
}
public class SmoothState extends AbsState {

public SmoothState(SpeedGenerator speedGenerator) {
super(speedGenerator);
}

이 도로의 상태를 가진 속도 생성자는 이 상태에 맞는 동작을 실행합니다.


이 동작은 AbsState에서 상속받아 구현한 동작들이고



이동작은 SpeedGenerator가 가진 세가지 상태와 그것들을 초기화하고
현재의 상태를 관리할 state를 만듭니다.

public class SpeedGenerator {
private AbsState sluggishState;
private AbsState slowlyState;
private AbsState smoothState;
private AbsState state;



public SpeedGenerator() {
sluggishState = new SluggishState(this);
slowlyState = new SlowlyState(this);
smoothState = new SmoothState(this);
}



public void setState(상황) {
if (조건) {
this.state = smoothState;
} else if (조건2) {
this.state = slowlyState;
} else if (조건3) {
this.state = sluggishState;
}
}

특정 상황에 맞는 조건이 왔을때 state의 상태는 변경되고 변경되 상태에 맞춰


public int generateSpeed(int speed) {
speed = state.generateSpeed(speed);
return speed;
}

public int smoothDescSpeed(int speed) {
speed = state.smoothDescSpeed(speed);
return speed;
}

public int smoothAscSpeed(int speed) {
speed = state.smoothAscSpeed(speed);
return speed;
}

public int stopSpeed(int speed) {
speed = state.stopSpeed(speed);
return speed;
}

public int stopAfterStart(int speed) {
speed = state.stopAfterStart(speed);
return speed;
}

State.동작을 부르면서 각 동작에 대해서는 캡슐화를 하고 상태에 따라 state를 호출합니다.

'IT > 개발경험기' 카테고리의 다른 글

Enum을 통한 개선경험  (0) 2019.12.19
[코틀린]의 위임 발표자료 공유  (0) 2019.12.01