상태 패턴
전략 패턴과 상태 패턴을 쌍둥이다?!
전략패턴(Strategy Pattern
)을 사용하면 행위(알고리즘
)을 캡슐화해서 객체가 행위 자체 변경할 수 있습니다.
상태패턴(State Pattern
)을 사용하면 객체의 내부 상태
를 캡슐화해서 상태 변경에 따라서 객체의 행동을 바꿀 수 있습니다.
쉽게 이야기 하면, 상태 패턴은 내부 상태를 바꿈으로써 객체가 행동을 바꿀 수 있도록 한다.
다시 말하면 상태에 따라서 행동을 달리해야하는 경우에 사용하는 패턴이다.
상태를 별도의 클래스로 캡슐화한 다음 현재 상태를 나타내는 객체에게 행동을 위임하므로 내부 상태가 바뀔 때 행동이 달라지게 된다.
4강 상태를 제외하고 모든 상태가 같다..!
상태 패턴 구조
- Context
- 해당 클래스에는 여러가지 내부 상태가 들어있을 수 있다.
request()
- 해당 메소드가 호출되면 그 작업은 상태 객체에 맡겨진다.
- State
- 모든 구상 상태 클래스의 공통 인터페이스
- ConcreteState1, ConcreteState2
Context
로부터 전달된 요청을 자기 나름의 방식으로 구현Context
에서 상태를 변경할 때마다 행동도 변경된다.
전략 패턴 VS 상태 패턴
상태 패턴과 전략 패턴의 다이어그램은 똑같다.
하지만 둘의 패턴의 용도는 완전히 다르다…!
상태 패턴
을 사용할 때는 상태 객체에 일련의 행동이 캡슐화됩니다.
상황에 따라서 Context
객체에서 여러 상태 객체 중 한 객체에게 모든 행동을 맡기게 됩니다.
그 객체의 내부 상태에 따라 현재 상태객체가 바뀌게 되고, 그 결과로 Context
객체의 행동도 자연스럽게 변경됩니다.
Context 객체에 상태에 따른 수많은 조건문을 넣는 대신에 상태 패턴을 사용한다고 생각하면 됩니다.
클라이언트는 상태 객체를 몰라도 됩니다…!!
전략 패턴
을 사용할 때는 일반적으로 클라리언트가 Context
객체에게 어떤 전략 객체를 사용할지를 지정해 줍니다.
전략 패턴은 주로 실행 시에 전략 객체를 변경할 수 있는 유연성을 제공하는 용도로 사용합니다.Context
가 전략 객체를 선택해서 사용하게 됩니다.
전략 패턴은 상속을 대체하려는 목적으로, 상태 패턴은 코드내의 조건문들을 대체하려는 목적으로 사용합니다.
티켓 머신 어플리케이션 개발
동전을 넣으면 티켓을 뽑을 수 있는 어플리케이션을 상태 패턴을 사용해서 개발해보자.!
State
public interface State {
void insertCoin();
void printTicket();
}
HasCoinState
public class HasCoinState implements State {
private TicketMachine ticketMachine;
public HasCoinState(TicketMachine ticketMachine) {
this.ticketMachine = ticketMachine;
}
@Override
public void insertCoin() {
System.out.println("이미 동전이 들어 있습니다.");
}
@Override
public void printTicket() {
// 상태 변경
ticketMachine.setState(ticketMachine.getNoCoinState());
System.out.println("사진 출력 완료!");
}
}
NoCoinState
public class NoCoinState implements State {
private TicketMachine ticketMachine;
public NoCoinState(TicketMachine ticketMachine) {
this.ticketMachine = ticketMachine;
}
@Override
public void insertCoin() {
// 상태 변경
ticketMachine.setState(ticketMachine.getHasCoinState());
System.out.println("동전 투입완료!");
}
@Override
public void printTicket() {
System.out.println("동전이 없습니다. 동전을 넣어주세요.");
}
}
TicketMachine
@Getter //롬복 사용
public class TicketMachine {
private State hasCoinState;
private State noCoinState;
private State state;
public TicketMachine() {
this.hasCoinState = new HasCoinState(this);
this.noCoinState = new NoCoinState(this);
this.state = this.noCoinState;
}
public void setState(State state) {
this.state = state;
}
public void insertCoin() {
state.insertCoin();
}
public void printTicket() {
state.printTicket();
}
}
TicketMachineDrive
public class TicketMachineDrive {
public static void main(String[] args) {
TicketMachine ticketMachine = new TicketMachine();
ticketMachine.insertCoin();
ticketMachine.printTicket();
ticketMachine.printTicket();
}
}
결과
동전 투입완료!
사진 출력 완료!
동전이 없습니다. 동전을 넣어주세요.
정리
- 상태 패턴을 사용하면 내부 상태를 바탕으로 여러 가지 서로 다른 행동을 사용 할 수 있습니다.
- 각 상태를 클래스로 표현합니다.
Context
객체는 현재 상태에게 행동을 위임합니다.- 각 상태를 클래스로 캡슐화해서 나중에 변경해야 하는 내용을 국지화할 수 있습니다.
Context
의 내부 상태가 바뀜에 따라 객체가 알아서 행동을 바꿀 수 있도록 할 수 있습니다.- 상태 패턴을 사용하면 디자인에 필요한 클래스의 갯수가 늘어납니다.
'컴퓨터과학 > 0 + 소프트웨어 아키텍처(디자인 패턴)' 카테고리의 다른 글
[소프트웨어 아키텍처] 5. 템플릿 메소드 패턴(Template method Pattern -java) (0) | 2022.10.25 |
---|---|
[소프트웨어 아키텍처] 2. 전략 패턴(Strategy Pattern -java) (0) | 2022.10.25 |
[소프트웨어 아키텍처] 3. 커맨드 패턴(Command Pattern-java) (0) | 2022.10.20 |
[소프트웨어 아키텍처] 4. 옵저버 패턴(Observer Pattern -java) (0) | 2022.10.10 |
[소프트웨어 아키텍처] 1-3) 아키텍처 패턴 스타일 (2) | 2022.09.20 |