LoginSignup
1
0

More than 5 years have passed since last update.

GoFのデザインパターン「observer」をrubyで実装してみた

Last updated at Posted at 2018-05-06

observerパターンは、観察対象の状態が変化すると観察舎に対して通知を送るような仕組みです。

rubyには observer が標準で組み込まれているので、今回はそれを用いて以下のように実装しました。

require 'observer'

# Observer役
class Observer
end

# Observer役
class DigitObserver < Observer
  def update(number)
    puts "DigitObserver: #{number}"
  end
end

# Observer役
# Observer役の追加が非常に簡単である。
class GraphObserver < Observer
  def update(number)
    string = '*'
    puts "GraphObserver: #{string*number}"
  end
end


# Subject役
class NumberGenerator
  include Observable
end

# ConcreteSubject役
class RandomNumberGenerator < NumberGenerator
  def run
    random = Random.new
    for i in 1..20 do
      number = random.rand(50)
      changed
      notify_observers(number)
    end
  end
end

# ConcreteSubject役
# Observer役と同じく、観察対象の追加が非常に簡単に実装できる。
class IncrementNumberGenerator < NumberGenerator
  def initialize(start_int, end_int, interval)
    unless (end_int - start_int) % interval == 0
      raise '正しい初期値を。'
    end

    @start_int = start_int
    @end_int = end_int
    @interval = interval
  end

  def run
    for i in 0..(@end_int - @start_int) / @interval
      changed
      notify_observers(@start_int + i * @interval)
    end
  end
end


generator = RandomNumberGenerator.new
generator.add_observer(DigitObserver.new)
generator.add_observer(GraphObserver.new)
generator.run

generator = IncrementNumberGenerator.new(10, 50, 5)
generator.add_observer(DigitObserver.new)
generator.add_observer(GraphObserver.new)
generator.run

結果

DigitObserver: 15
GraphObserver: ***************
DigitObserver: 23
GraphObserver: ***********************
DigitObserver: 0
GraphObserver: 
DigitObserver: 5
GraphObserver: *****
DigitObserver: 41
GraphObserver: *****************************************
DigitObserver: 6
GraphObserver: ******
DigitObserver: 30
GraphObserver: ******************************
DigitObserver: 41
GraphObserver: *****************************************
DigitObserver: 6
GraphObserver: ******
DigitObserver: 28
GraphObserver: ****************************
DigitObserver: 15
GraphObserver: ***************
DigitObserver: 31
GraphObserver: *******************************
DigitObserver: 47
GraphObserver: ***********************************************
DigitObserver: 11
GraphObserver: ***********
DigitObserver: 30
GraphObserver: ******************************
DigitObserver: 29
GraphObserver: *****************************
DigitObserver: 41
GraphObserver: *****************************************
DigitObserver: 34
GraphObserver: **********************************
DigitObserver: 24
GraphObserver: ************************
DigitObserver: 13
GraphObserver: *************
DigitObserver: 10
GraphObserver: **********
DigitObserver: 15
GraphObserver: ***************
DigitObserver: 20
GraphObserver: ********************
DigitObserver: 25
GraphObserver: *************************
DigitObserver: 30
GraphObserver: ******************************
DigitObserver: 35
GraphObserver: ***********************************
DigitObserver: 40
GraphObserver: ****************************************
DigitObserver: 45
GraphObserver: *********************************************
DigitObserver: 50
GraphObserver: **************************************************
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0