倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

「GoF デザインパターン」アノテーション (20) : State パターン

今回は State パターン一覧)。

State パターンの登場人物

  • @Context → 型
    • stateType : Class<?>
    • @StateInstance → フィールド
  • @State → 型
  • @ConcreteState → 具象クラス
    • stateType : Class<?>

アノテーション定義


上記の定義の具体的な Java コード。

package org.waman.tools.design.gof.behavioral;

import java.lang.annotation.*;

public final class StatePattern {
    
    private StatePattern(){}

    @Target(ElementType.TYPE)
    public static @interface Context{

        Class<?> stateType() default Void.class;

        @Inherited @Target(ElementType.FIELD)
        public static @interface StateInstance{}
    }

    @Target(ElementType.TYPE)
    public static @interface State{}

    @Target(ElementType.TYPE)
    public static @interface ConcreteState{
        Class<?> stateType() default Void.class;
    }
}

サンプルコード in 『Java 言語で学ぶデザインパターン入門』

State.java

@State 役のインターフェース。

import org.waman.tools.design.gof.behavioral.StatePattern;

@StatePattern.State
public interface State {
    void doClock(Context context, int hour);
    void doUse(Context context);
    void doAlarm(Context context);
    void doPhone(Context context);
}

DayState.java, NightState.java

@ConcreteState 役の具象クラス。

import org.waman.tools.design.gof.behavioral.StatePattern;

@StatePattern.ConcreteState(stateType = State.class)
public class DayState implements State {
    
    private static DayState INSTANCE = new DayState();
    
    private DayState() {}
    
    public static State getInstance() {
        return INSTANCE;
    }
    
    @Override public void doClock(Context context, int hour) {
        if (hour < 9 || 17 <= hour) {
            context.changeState(NightState.getInstance());
        }
    }
    
    @Override public void doUse(Context context) {...}
    @Override public void doAlarm(Context context) {...}
    @Override public void doPhone(Context context) {...}
    @Override public String toString() {...}
}
import org.waman.tools.design.gof.behavioral.StatePattern;

@StatePattern.ConcreteState(stateType = State.class)
public class NightState implements State {
    
    private static NightState INSTANCE = new NightState();
    
    private NightState() {}
    
    public static State getInstance() {
        return INSTANCE;
    }
    
    @Override public void doClock(Context context, int hour) {
        if (9 <= hour && hour < 17) {
            context.changeState(DayState.getInstance());
        }
    }
    
    @Override public void doUse(Context context) {...}
    @Override public void doAlarm(Context context) {...}
    @Override public void doPhone(Context context) {...}
    @Override public String toString() {...}
}

Context.java, SafeFrame.java

@Context 役のインターフェース。

import org.waman.tools.design.gof.behavioral.StatePattern;

@StatePattern.Context(stateType = State.class)
public interface Context {

    void setClock(int hour);
    void changeState(State state);
    void callSecurityCenter(String msg);
    void recordLog(String msg);
}
import java.awt.*;
import java.awt.event.*;
import org.waman.tools.design.gof.behavioral.StatePattern;
import org.waman.tools.design.gof.behavioral.StatePattern.Context.StateInstance;

@StatePattern.Context(stateType = State.class)
public class SafeFrame extends Frame implements ActionListener, Context {
    
    private static final long serialVersionUID = 3783785921440683138L;
    @StateInstance private State state = DayState.getInstance();
    ...

    ...
    @Override public void setClock(int hour) {...}
    @Override public void changeState(State state) {...}
    @Override public void callSecurityCenter(String msg) {...}
    @Override public void recordLog(String msg) {...}
}

増補改訂版Java言語で学ぶデザインパターン入門 オブジェクト指向における再利用のためのデザインパターン Code Complete第2版〈上〉―完全なプログラミングを目指して Code Complete第2版〈下〉―完全なプログラミングを目指して