25
GoFのデザインパターン Stateパターン編 2013/03/01(金) 伊藤歩

Gofのデザインパターン stateパターン編

Embed Size (px)

Citation preview

Page 1: Gofのデザインパターン stateパターン編

GoFのデザインパターン

Stateパターン編

2013/03/01(金)伊藤歩

Page 2: Gofのデザインパターン stateパターン編

本日のアジェンダ

・デザインパターンとは・Stateパターンの具体例

・Stateパターンのメリット

・デザインパターンの注意点

Page 3: Gofのデザインパターン stateパターン編

デザインパターンとは

過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものである。

wikipediaより

Page 4: Gofのデザインパターン stateパターン編

過去のソフトウェア設計者

Page 5: Gofのデザインパターン stateパターン編

過去のソフトウェア設計者

Gang of Four(ギャング・オブ・フォー、四人組)

Page 6: Gofのデザインパターン stateパターン編

Stateパターンの具体例サンプル

PLAY、STOP、PAUSEという状態がある

各状態で特定のコマンドを実行した時、違う挙動をするプログラムを作成する。

Page 7: Gofのデザインパターン stateパターン編

// コマンドqを受け取った場合

if (s.equals("q")) {if (mState == STATE_PLAY) {

System.out.println("STATE_PLAY:q");} else if (mState == STATE_STOP) {

System.out.println("STATE_STO::q");} else if (mState == STATE_PAUSE) {

System.out.println("STATE_PAUSE:q");}

}

if文で分岐させると・・・

Page 8: Gofのデザインパターン stateパターン編

// コマンドwを受け取った場合

if (s.equals("w")) {if (mState == STATE_PLAY) {

System.out.println("STATE_PLAY:w");} else if (mState == STATE_STOP) {

System.out.println("STATE_STOP:w");} else if (mState == STATE_PAUSE) {

System.out.println("STATE_PAUSE:w");}

}

if文で分岐させると・・・

Page 9: Gofのデザインパターン stateパターン編

// コマンドeを受け取った場合

if (s.equals("e")) {if (mState == STATE_PLAY) {

System.out.println("STATE_PLAY:e");} else if (mState == STATE_STOP) {

System.out.println("STATE_STOP:e");} else if (mState == STATE_PAUSE) {

System.out.println("STATE_PAUSE:e");}

}

if文で分岐させると・・・

Page 10: Gofのデザインパターン stateパターン編

さぁ野郎ども、

仕様追加のお時間だ!

Page 11: Gofのデザインパターン stateパターン編

さぁ野郎ども、

仕様追加のお時間だ!

コマンド”r”も追加な。※全部の状態で。

Page 12: Gofのデザインパターン stateパターン編

// コマンドrを受け取った場合

if (s.equals("r")) {if (mState == STATE_PLAY) {

System.out.println("STATE_PLAY:r");} else if (mState == STATE_STOP) {

System.out.println("STATE_STOP:r");} else if (mState == STATE_PAUSE) {

System.out.println("STATE_PAUSE:r");}

}

そしてこうなる

Page 13: Gofのデザインパターン stateパターン編

喜べ野郎ども、

また仕様追加だ!!!

Page 14: Gofのデザインパターン stateパターン編

喜べ野郎ども、

また仕様追加だ!!!

状態RECを追加な!※全部のコマンドで

Page 15: Gofのデザインパターン stateパターン編

喜べ野郎ども、

また仕様追加だ!!!

状態RECを追加な!※全部のコマンドで

Page 16: Gofのデザインパターン stateパターン編

状態×コマンド分の分岐が発生・・・

if文地獄の幕開けである。

Page 17: Gofのデザインパターン stateパターン編

そんなときにStateパターン

状態をクラスとして設計。

Page 18: Gofのデザインパターン stateパターン編

状態をクラスとして設計。

オブジェクトの状態に応じて、挙動を変える場合に有効。

そんなときにStateパターン

Page 19: Gofのデザインパターン stateパターン編

Stateパターンのクラス図

Page 20: Gofのデザインパターン stateパターン編

public interface State {void func_q();void func_w();void func_e();void func_r();

}

状態に応じたInterfaceを用意

Page 21: Gofのデザインパターン stateパターン編

public class PlayState implements State {public void func_q(){

System.out.println("STATE_PLAY:q");}public void func_w() {

System.out.println("STATE_PLAY:w");}public void func_e() {

System.out.println("STATE_PLAY:e");}public void func_r() {

System.out.println("STATE_PLAY:r");}

}

Interfaceを実装する状態クラス作成

StopやPauseも同様に、StateのInterfaceを実装します。

Page 22: Gofのデザインパターン stateパターン編

State state = null;if (n == STATE_PLAY) {

state = new PlayState();} else if (n == STATE_STOP) {

state = new StopState();} else if (n == STATE_PAUSE) {

state = new PauseState();}

状態によって、

オブジェクトを切り替える

Page 23: Gofのデザインパターン stateパターン編

// コマンドに応じて処理を実行

if (s.equals("q")) {state.func_q();

}if (s.equals("w")) {

state.func_w();}if (s.equals("e")) {

state.func_e();}

あとはメソッドを呼ぶだけ

Page 24: Gofのデザインパターン stateパターン編

Stateパターンのメリット

・コマンドや状態の追加で既存に影響ない。

・処理の修正は各Stateクラスで閉じる。

・コードの見通しが良くなる。

影響範囲が少ないので、デバッグ工数が削減可能。

保守性の向上。

Page 25: Gofのデザインパターン stateパターン編

デザインパターンの注意点

無理に導入しない。

Stateパターン使う俺カッコイイ(・∀・)みたいなノリで、使うのはNG。

あくまでオブジェクトの状態に応じて、挙動を変える場合に有効。