概要
GoFのデザインパターンのStateパターンについて。
状態をクラスで表現します。
状態と処理を分割することでプログラムをよりシンプルにします。
登場人物
State = 状態。状態に依存した振る舞いを表す
ConcreteState = 具象状態
Context = 状況、文脈
実装サンプル
サンプル概要
1日の生活を起床、行動、就寝に分けて出力します。
状態は日にちの種別として、平日と週末の2つにわかれます。
平日は7時に起床、会社で仕事、25時に就寝します。
週末は10時に起床、だらだら過ごす、27時に就寝します。
登場人物
State = DateOfTheWeek :状態。状態に依存した振る舞いを表す
ConcreteState = Weekday : 具象状態
ConcreteState = Weekend : 具象状態
Context = DailyAction : 状況、文脈
サンプルコード
DateOfTheWeek
# encoding: Shift_JIS =begin rdoc = DayOfTheWeekクラス =end class DayOfTheWeek NOT_OVERRRIDE = 'not override error' def wake_up() raise DayOfTheWeek::NOT_OVERRRIDE end def act() raise DayOfTheWeek::NOT_OVERRRIDE end def going_to_bed() raise DayOfTheWeek::NOT_OVERRRIDE end def set_date(daily_action, date) raise DayOfTheWeek::NOT_OVERRRIDE end end
Weekday
# encoding: Shift_JIS require_relative './daily_action' require_relative './day_of_the_week' require_relative './weekend' =begin rdoc = Weekdayクラス =end class Weekday < DayOfTheWeek def wake_up() return "7時" end def act() return "仕事" end def going_to_bed() return "25時" end def set_date(daily_action, date) if (date.wday == 0 || date.wday == 6) daily_action.change_date Weekend.new end end end
Weekend
# encoding: Shift_JIS require_relative './daily_action' require_relative './day_of_the_week' require_relative './weekday' =begin rdoc = Weekendクラス =end class Weekend < DayOfTheWeek def wake_up() return "10時" end def act() return "ダラダラ" end def going_to_bed() return "27時" end def set_date(daily_action, date) unless (date.wday == 0 || date.wday == 6) daily_action.change_date Weekday.new end end end
DailyAction
# encoding: Shift_JIS require_relative './day_of_the_week' require_relative './weekday' =begin rdoc = DailyActionクラス =end class DailyAction attr_accessor :day_of_the_week def initialize() @day_of_the_week = Weekday.new end def wake_up() return "#{@day_of_the_week.wake_up}に起きます" end def act() return "#{@day_of_the_week.act}をします" end def going_to_bed() return "#{@day_of_the_week.going_to_bed}に寝ます" end def set_date(date) @day_of_the_week.set_date self,date end def change_date(day_of_the_week) @day_of_the_week = day_of_the_week end end
main
# encoding: Shift_JIS require 'date' require_relative './daily_action' daily_action = DailyAction.new date = Date.new(2012, 3, 2) daily_action.set_date(date) puts daily_action.wake_up puts daily_action.act puts daily_action.going_to_bed puts "----------------------------------------------" date = Date.new(2012, 3, 3) daily_action.set_date(date) puts daily_action.wake_up puts daily_action.act puts daily_action.going_to_bed puts "----------------------------------------------" date = Date.new(2012, 3, 4) daily_action.set_date(date) puts daily_action.wake_up puts daily_action.act puts daily_action.going_to_bed puts "----------------------------------------------" date = Date.new(2012, 3, 5) daily_action.set_date(date) puts daily_action.wake_up puts daily_action.act puts daily_action.going_to_bed puts "----------------------------------------------"
出力結果
7時に起きます 仕事をします 25時に寝ます ---------------------------------------------- 10時に起きます ダラダラをします 27時に寝ます ---------------------------------------------- 10時に起きます ダラダラをします 27時に寝ます ---------------------------------------------- 7時に起きます 仕事をします 25時に寝ます ----------------------------------------------