君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

劇的ビフォ◯アフターで学ぶデザインパターン(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パターンを適用してみます。