오랜만에 글을 작성하네요-_-
태안에 조개잡이를 떠났다가
여자친구가 모기에
50방을 물렸네요-_-
모기에게 100% 물리지 않는
어떤 약이나 도구가
발명된다면 대박일듯...
아무튼 이번 학습 주제는
상태(State) 패턴입니다
객체 지향 프로그래밍에서는
프로그램 할 대상을
클래스(Class)로 표현하고
이것을 설계해야합니다
오늘 학습할 상태 패턴은
상태를 클래스로
표현하는 패턴입니다
그럼 상태 패턴의
역할들을 정리하고
시작하겠습니다
역할 | 설명 |
State(상태) | 상태를 나타내며 상태가 변할 때마다 다른 동작을 하는 인터페이스를 결정 |
Concrete State(구체적인 상태) | 구체적인 각각의 상태를 표현하고 State 역할로 결정되는 인터페이스를 구체적으로 구현 |
Context(문맥) | 현재의 상태를 나타내는 Concrete State 역할을 가지며 State 패턴의 이용자에게 필요한 인터페이스를 결정 |
역할 정리만으로는
이해하기가 어렵네요-_-
구현해보겠습니다
1. 인터페이스(Interface) State.java
package statePattern;
public interface State {
public abstract void doClock(Context context, int hour);
public abstract void doUse(Context context);
public abstract void doAlarm(Context context);
public abstract void doPhone(Context context);
}
2. 클래스(Class) DayState.java
package statePattern;
public class DayState implements State {
private static DayState singleton = new DayState();
private DayState() {
}
public static State getInstance() {
return singleton;
}
public void doClock(Context context, int hour) {
if ( hour < 9 || 17 <= hour ) {
context.changeState(NightState.getInstance());
}
}
public void doUse(Context context) {
context.recordLog("금고사용(주간)");
}
public void doAlarm(Context context) {
context.callSecurityCenter("비상벨(주간)");
}
public void doPhone(Context context) {
context.callSecurityCenter("일반통화(주간)");
}
public String toString() {
return "[주간]";
}
}
3. 클래스(Class) NightState.java
package statePattern;
public class NightState implements State {
private static NightState singleton = new NightState();
private NightState() {
}
public static State getInstance() {
return singleton;
}
public void doClock(Context context, int hour) {
if ( hour >= 9 && 17 > hour ) {
context.changeState(DayState.getInstance());
}
}
public void doUse(Context context) {
context.recordLog("비상 : 야간금고 사용!");
}
public void doAlarm(Context context) {
context.callSecurityCenter("비상벨(야간)");
}
public void doPhone(Context context) {
context.callSecurityCenter("야간통화 녹음");
}
public String toString() {
return "[야간]";
}
}
4. 인터페이스(Interface) Context.java
package statePattern;
public interface Context {
public abstract void setClock(int hour);
public abstract void changeState(State state);
public abstract void callSecurityCenter(String msg);
public abstract void recordLog(String msg);
}
5. 클래스(Class) SafeFrame.java
package statePattern;
import java.awt.*;
import java.awt.event.*;
public class SafeFrame extends Frame implements ActionListener, Context {
private TextField textClock = new TextField(60);
private TextArea textScreen = new TextArea(10, 60);
private Button buttonUse = new Button("금고사용");
private Button buttonAlarm = new Button("비상벨");
private Button buttonPhone = new Button("일반통화");
private Button buttonExit = new Button("종료");
private State state = DayState.getInstance();
public SafeFrame(String title) {
super(title);
setBackground(Color.lightGray);
setLayout(new BorderLayout());
add(textClock, BorderLayout.NORTH);
textClock.setEditable(false);
add(textScreen, BorderLayout.CENTER);
textScreen.setEditable(false);
Panel panel = new Panel();
panel.add(buttonUse);
panel.add(buttonAlarm);
panel.add(buttonPhone);
panel.add(buttonExit);
add(panel, BorderLayout.SOUTH);
pack();
show();
buttonUse.addActionListener(this);
buttonAlarm.addActionListener(this);
buttonPhone.addActionListener(this);
buttonExit.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
if ( e.getSource() == buttonUse ) {
state.doUse(this);
} else if ( e.getSource() == buttonAlarm ) {
state.doAlarm(this);
} else if ( e.getSource() == buttonPhone ) {
state.doPhone(this);
} else if ( e.getSource() == buttonExit ) {
System.exit(0);
} else {
System.out.println("?");
}
}
public void setClock(int hour) {
String clockstring = "현재 시간은";
if ( hour < 10 ) {
clockstring += "0" + hour + ":00";
} else {
clockstring += hour + ":00";
}
System.out.println(clockstring);
textClock.setText(clockstring);
state.doClock(this, hour);
}
public void changeState(State state) {
System.out.println(this.state + "에서" + state + "로 상태가 변화했습니다.");
this.state = state;
}
public void callSecurityCenter(String msg) {
textScreen.append("call! " + msg + "\n");
}
public void recordLog(String msg) {
textScreen.append("record ... " + msg + "\n");
}
}
6. 클래스(Class) Test.java
import statePattern.*;
public class Test {
public static void main(String[] args) {
SafeFrame frame = new SafeFrame("State Sample");
while ( true ) {
for ( int hour = 0; hour < 24; hour++ ) {
frame.setClock(hour);
try {
Thread.sleep(1000);
} catch ( InterruptedException e ) {
}
}
}
}
}
위의 코드에서
DayState와 LightState를
싱글톤(Singleton) 패턴으로
구현하고 있습니다
싱글톤 패턴에 대해
궁금하시다면
아래의 링크로 ↓↓
2020/06/14 - [Java] - [Design Pattern] 싱글톤(Singleton) 패턴과 프로토타입(Prototype) 패턴
상태 패턴은
상태를 클래스로 표현해서
복잡한 프로그램을 분할하며
이느 Divide & Conquer 방침을
이행하고 있습니다
그런데 이 패턴은
상태전환을 Concrete State 역할
(DayState, LightState)이 하며
이것은 둘의 의존도를 높이는
단점이 있습니다
이번 학습은
여기서 마치고
다음 학습 주제는
플라이급(Flyweight)
패턴에 대해 알아보겠습니다
그럼 이만-_-
'Java' 카테고리의 다른 글
[Design Pattern] 대리인 패턴(Proxy Pattern) (0) | 2020.07.22 |
---|---|
[Design Pattern] 플라이급 패턴(Flyweight Pattern) (0) | 2020.07.21 |
[Design Pattern] 추억거리 패턴(Memento Pattern) (0) | 2020.07.16 |
[Design Pattern] 관찰자 패턴(Observer Pattern) (0) | 2020.07.15 |
[Design Pattern] 창구 패턴(Facade Pattern)과 중개자 패턴(Mediator Pattern) (0) | 2020.07.13 |