劇的ビフォ◯アフターで学ぶデザインパターン(state編:before)
デザインパターンのメリットについて今一度確認したい
業務で使ったり使わなかったりするデザインパターンですが、
なかなかメリットについてつきつめて考えたことがない。
「なんとなくソースコードがきれいになった気がする。。。」で頭がとまってしまっている><
そこで、デザインパターンを利用する前/後を比較することにより
今一度メリットを確かめてみることにしました。
今回はstateパターンで。
心理的状態によっていろんなhelloを返す人間クラス
class Human # その人心理的状態 attr_accessor :state # 普通 STATE_NORMAL = 0 # 嬉しい時 STATE_HAPPY = 1 # 風邪を引いた時 STATE_COLD = 2 def initialize(state = STATE_NORMAL) # 引数が渡ってきていない場合、デフォルトでNORMALにする @state = state end # 挨拶をさせる def hello if state == STATE_NORMAL puts 'hello.' elsif state == STATE_HAPPY puts 'hello!!!' elsif state == STATE_COLD puts 'hello...' end end # 挨拶をさせる def goodbye if state == STATE_NORMAL puts 'goodbye.' elsif state == STATE_HAPPY puts 'goodbye!!!' elsif state == STATE_COLD puts 'goodbye...' end end # 何も起きない def nothing_happens @state = STATE_NORMAL puts '(特に何もなかった。)' end # 試験に通ったから嬉しい def pass_a_exam @state = STATE_HAPPY puts '(試験に通った!)' end # 風邪を引いて元気がない def catch_a_cold @state = STATE_COLD puts '(風邪を引いた。。)' end end
クラスの利用側
human = Human.new
human.catch_a_cold
human.hello
human.goodbye
human.pass_a_exam
human.hello
human.goodbye
human.nothing_happens
human.hello
human.goodbye
結果
(風邪を引いた。。) hello... goodbye... (試験に通った!) hello!!! goodbye!!! (特に何もなかった。) hello. goodbye.
仕様変更
上司「このクラスに、”恋に落ちた状態”を追加してよ」
こんな仕様変更があったときの変更箇所について考えてみる。
class Human # その人心理的状態 attr_accessor :state # 普通 STATE_NORMAL = 0 # 嬉しい時 STATE_HAPPY = 1 # 風邪を引いた時 STATE_COLD = 2 ############### 1. 状態の追加 ############### def initialize(state = STATE_NORMAL) # 引数が渡ってきていない場合、デフォルトでNORMALにする @state = state end # 挨拶をさせる def hello if state == STATE_NORMAL puts 'hello.' elsif state == STATE_HAPPY puts 'hello!!!' elsif state == STATE_COLD puts 'hello...' end ############### 2. 分岐の追加 ############### end # 挨拶をさせる def goodbye if state == STATE_NORMAL puts 'goodbye.' elsif state == STATE_HAPPY puts 'goodbye!!!' elsif state == STATE_COLD puts 'goodbye...' end ############### 3. 分岐の追加 ############### end # 何も起きない def nothing_happens @state = STATE_NORMAL puts '(特に何もなかった。)' end # 試験に通ったから嬉しい def pass_a_exam @state = STATE_HAPPY puts '(試験に通った!)' end # 風邪を引いて元気がない def catch_a_cold @state = STATE_COLD puts '(風邪を引いた。。)' end ############### 4. 状態変化の追加 ############### end
4箇所変更の必要がある。
基本的に既存のソースコードを変更は少ないほど良い。
(規模によっては既存ソースコードの編集はリスクになるから)
stateパターン
このように、クラスが状態をいくつか持つときはstateパターンが有効。
本当に有効なのか?ということで次回、stateパターンを適用してみます。