1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

有限オートマトン(finite state machine)を単純化して考える

Posted at

有限オートマトン

Acca Actorでは、有限オートマトン(finite state machine)と呼ばれる振る舞いのモデルを用いることができる。
また、これを実装しやすくするために、FSMというトレイトが用意されている。(自ら実装してもよい)

ただし、有限オートマトンはAkka(Actor)がなくても成立する概念なので、
Actorの要素を取り除き、シンプルな有限オートマトンを実装して説明する。

有限オートマトン(wikipedia)
https://ja.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E3%82%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%88%E3%83%B3#UML%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%9E%E3%82%B7%E3%83%B3

有限オートマトン(finite state machine)を単純化して考える

State.Scala
/** 状態 */
sealed trait State{
  /** 振る舞い */
  type Behavior = Command => State
  /** 状態名 */
  val stateName: String
  /** 次の状態(コマンド→状態変換の振る舞い) */
  val getNextState : Behavior
}

/** 最終状態(もう状態変化が起こらない状態) */
sealed trait FinalState extends State {
  /** 次の状態(どのコマンドが来ても、今の状態に等しくなる) */
  override final val getNextState : Behavior = {
    case StartProcess => this
    case ProcessFinishSafety => this
  }
}

case object WaitingForRequest extends State {
  override val stateName: String = "WaitingForRequest"
  override val getNextState : Behavior = {
    case StartProcess => Processing
    case ProcessFinishSafety => Terminated
  }
}

case object Processing extends State {
  override val stateName: String = "Processing"
  override val getNextState : Behavior = {
    case StartProcess => Terminated
    case ProcessFinishSafety => Finished
  }
}

case object Finished extends FinalState {
  override val stateName: String = "Finished"
}

case object Terminated extends FinalState {
  override val stateName: String = "Terminated"
}
Command.Scala
/** コマンド */
sealed trait Command
/** 処理を開始させるコマンド */
case object StartProcess extends Command
/** 処理中に安全に終了させるコマンド */
case object ProcessFinishSafety extends Command
FakeActor.Scala
import java.util.Objects

/** AkkaActor要素を取り除いた有限状態マシン。Akka Actorを使用する場合は、この部分が実際のActorとなる。 */
final class FakeActor(){
  /** 状態(初期状態) */
  private var state : State = WaitingForRequest
  /** 状態の確認 */
  def getState : String = state.stateName

  /**
   * コマンドを送信して、状態を変更する
   * @param command コマンド
   * @return 結果、状態が変動するか
   */
  def goNextState(command: Command): Boolean = {
    val next: State = state.getNextState(command)
    val changed: Boolean = !Objects.equals(state,next)
    state = next
    changed
  }
}

Applicationからの利用

trait.Scala
object Application extends App {
  System.out.println("-------SUCCESS--------")
  val success = FakeActor()
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(StartProcess))
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(ProcessFinishSafety))
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(StartProcess))
  System.out.println(success.getState)

  System.out.println("-------FAILED--------")
  val failed = FakeActor()
  System.out.println(failed.getState)
  System.out.println("changed:" + failed.goNextState(ProcessFinishSafety))
  System.out.println(failed.getState)
  System.out.println("changed:" + failed.goNextState(StartProcess))
  System.out.println(failed.getState)
}
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?