Rubyでデザインパターン ~Stateパターン~
RubyでStateパターンを実装してみるテスト。
Stateのコンクリートクラスにメソッドの実装を生やすことで、Stateを新しく追加するときに追加しやすくしている。
クラスマクロもちょろっと使ってみたり。
でもクラスマクロはコードが短くなるのはいいけど、初見の人には読みづらいと思うんだよなぁ。
class Class def subclasses subclasses = [] ObjectSpace.each_object(singleton_class) do |k| subclasses << k if k.superclass == self end subclasses end end class State @_time def self.time(time=nil) # 引数がnilの時はgetter, nilでない時はsetterになる @_time ||= time end def time # インスタンスメソッドも一応定義しておく self.class.instance_variable_get("@_time") end def hello raise end end class MorningState < State time 0..9 def hello puts "Good morning!" end end class DayState < State time 10..15 def hello puts "Hello!" end end class EveningState < State time 16..18 def hello puts "Good evening." end end class NightState < State time 19..24 def hello puts "Good night." end end class StateManager attr_accessor :state, :time def initialize(state=MorningState.new) @state = state end def say_hello @state.hello end def time=(time) @time = time State::subclasses.each do |k| if k.time.include?(@time) @state = k.new break end end end end mgr = StateManager.new mgr.say_hello (0..24).to_a.each do |i| mgr.time = i mgr.say_hello end