UMLによるStateパターン[1][2]
Lepus3英語版によるStateパターン[2][3]

State パターン: state pattern、ステート・パターン)とは、プログラミングで用いられる振る舞いに関する英語版 デザインパターンの一種である。このパターンはオブジェクトの状態(state)を表現するために用いられる。ランタイムでそのタイプを部分的に変化させるオブジェクトを扱うクリーンな手段となる[1]:395

擬似コードによる例

編集

ドローソフトを例に取る。このプログラムは任意の時点においてさまざまなツールのうちの1つとして振る舞うマウスカーソルを持つ。複数のカーソルオブジェクトを切り替える代わりに、カーソルは現在使用されているツールを表す内部的な状態を保持する。(例えばマウスクリックの結果として)ツールに依存するメソッドが呼ばれると、メソッド呼び出しはカーソルの状態へと渡される。

各ツールは1つの状態に対応している。共有される抽象状態クラスはAbstractToolである。

 class AbstractTool is
     function moveTo(point) is
         input:  the location point the mouse moved to
         (this function must be implemented by subclasses)
 
     function mouseDown(point) is
         input:  the location point the mouse is at
         (this function must be implemented by subclasses)
 
     function mouseUp(point) is
         input:  the location point the mouse is at
         (this function must be implemented by subclasses)

この定義により、各ツールはマウスカーソルの移動およびクリック/ドラッグの開始と終了を扱わなければならない。

その基底クラスを用い、単純なペンと範囲選択の各ツールを定義すると以下のようになる。

 subclass PenTool of AbstractTool is
     last_mouse_position := invalid
     mouse_button := up
 
     function moveTo(point) is
         input:  the location point the mouse moved to
         if mouse_button = down
             (draw a line from the last_mouse_position to point)
             last_mouse_position := point
 
     function mouseDown(point) is
         input:  the location point the mouse is at
         mouse_button := down
         last_mouse_position := point
 
     function mouseUp(point) is
         input:  the location point the mouse is at
         mouse_button := up
 
 
 subclass SelectionTool of AbstractTool is
     selection_start := invalid
     mouse_button := up
 
     function moveTo(point) is
         input:  the location point the mouse moved to
         if mouse_button = down
             (select the rectangle between selection_start and point)
 
     function mouseDown(point) is
         input:  the location point the mouse is at
         mouse_button := down
         selection_start := point
 
     function mouseUp(point) is
         input:  the location point the mouse is at
         mouse_button := up


この例では、コンテキストのためのクラスはCursorと呼ばれている。抽象状態クラス(この場合AbstractTool)で名付けられたメソッド群はコンテキストにおいても実装されている。コンテキストクラスではこれらのメソッドは、current_toolにより表される現在の状態の、対応するメソッドを呼び出す。

 class Cursor is
     current_tool := new PenTool
 
     function moveTo(point) is
         input:  the location point the mouse moved to
         current_tool.moveTo(point)
 
     function mouseDown(point) is
         input:  the location point the mouse is at
         current_tool.mouseDown(point)
 
     function mouseUp(point) is
         input:  the location point the mouse is at
         current_tool.mouseUp(point)
 
     function usePenTool() is
         current_tool := new PenTool
 
     function useSelectionTool() is
         current_tool := new SelectionTool

Cursorオブジェクトが、適切なメソッド呼び出しをアクティブとなっているツールへと渡すことにより、異なる時点においてPenToolとSelectionToolのどちらとしてでも振舞えるのである。これがStateパターンの本質である。この場合では、PenCursorクラスとSelectCursorクラスを作ることで状態とオブジェクトを結合することも可能であり、単なる継承へと単純化できたであろうが、実践においては新しいツールが選択される毎に新しいオブジェクトへとコピーするにはコストがかかりすぎたりエレガントでなかったりするようなデータをCursorが保持していることもあるであろう。

Javaによる例

編集

以下は状態(State)のインタフェースと2つの実装である。状態メソッドはコンテキストオブジェクトへの参照を持ち、その状態を変えることができる。

interface State {
	void writeName(StateContext stateContext, String name);
}

class StateA implements State {
	public void writeName(StateContext stateContext, String name) {
		System.out.println(name.toLowerCase());
		// コンテキストをStateBに遷移する
		stateContext.setState(new StateB());
	}
}

class StateB implements State {
	private int count = 0;
	public void writeName(StateContext stateContext, String name){ 
		System.out.println(name.toUpperCase()); 
		// StateBのwriteName()が2度呼び出された後にコンテキストをStateAに遷移する
		if (++count > 1) { 
			stateContext.setState(new StateA()); 
		}
	}
}

コンテキストクラスは、初期状態(この場合はStateA)でインスタンス生成したところの状態変数を持つ。そのメソッドでは、状態オブジェクトの対応するメソッドを使用する。

public class StateContext {
	private State myState;
	public StateContext() {
		setState(new StateA());
	}

	// 通常は、Stateインタフェースを実装しているクラスによってのみ呼び出される
	public void setState(State newState) {
		this.myState = newState;
	}

	public void writeName(String name) {
		this.myState.writeName(this, name);
	}
}

用法は以下。

public class TestClientState {
	public static void main(String[] args) {
		StateContext sc = new StateContext();
		sc.writeName("Monday");
		sc.writeName("Tuesday");
		sc.writeName("Wednesday");
		sc.writeName("Thursday");
		sc.writeName("Saturday");
		sc.writeName("Sunday");
	}
}

TestClientStateからのmain()の出力は次のようになるはずである。

monday
TUESDAY
WEDNESDAY
thursday
SATURDAY
SUNDAY


脚注

編集
  1. ^ a b Erich Gamma; Richard Helm, Ralph Johnson, John M. Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0201633612 エリック・ガンマラルフ・ジョンソンリチャード・ヘルムジョン・ブリシディース(著)、グラディ・ブーチ(まえがき)、本位田真一、吉田和樹(監訳)、『オブジェクト指向における再利用のためのデザインパターン』、ソフトバンクパブリッシング、1995年。ISBN 978-4797311129
  2. ^ a b State pattern in UML and in LePUS3
  3. ^ legend

関連項目

編集

外部リンク

編集

📚 Artikel Terkait di Wikipedia

Command パターン

receiver of the request." Gamma (1994). p.263. ^ "Commands are an object-oriented replacement for callbacks. " Gamma (1994) p.265. ^ Vcl.ActnList.TAction

コンピュータ略語一覧

Recognition) OO オブジェクト指向 (Object Oritented) OOo OpenOffice.org OOP オブジェクト指向プログラミング (Object Oriented Programming) OPS OPerator System 大型コンピュータのオペレーター制御装置 OS

アンチパターン

入力クラッジ(英語版)(input kludge) 正しくない入力の検出や扱いの失敗 暗室栽培(英語版)(mushroom management) 部下に情報を伝えなかったり、誤った情報を伝える(暗所で栽培する) システムのおんぼろ煙突化(英語版)(stovepipe system)

Fortran

and Procedures", Springer, 2009. ISBN 978-1-84628-378-9 Ed Akin: "Object-Oriented Programming via Fortran 90/95", Cambridge Univ Press, 2003年. ISBN 978-0-521-52408-7

Lola

コンパイラの中身の詳細はヴィルトの技術レポート Lola System Notes にある。デジタル設計に関するツール全体の概要は技術レポート Tools for Digital Circuit Design using FPGAs にある(Lola に関するレポート Lola: An Object-Oriented Logic Description

システムプログラミング言語

クセス手段を提供する。BCPLは、この意味での典型的なシステムプログラミング言語だった。システムプログラミング言語はしばしばビルトインの入出力(input/output; I/O)機能を欠いていた。かつては、システムソフトウェアが独自の基本的な入出力メカニズムを開発したり、基本的なモニタ入出力やス

CANape

referred to as CASL (Calculation and Scripting Language). CASL, is a signal-oriented language. CANape contains a function editor for writing cross-device functions

Zachmanフレームワーク

Repository Software. The One-VA EA repository was developed using an object oriented database within the Caliber-RM Software Product. Caliber-RM is intended