Application of observer pattern in design pattern in Ruby Programming

Time:2022-1-4

Observer mode(sometimes referred to as publish / subscribe mode) is softwareDesign patternA kind of.
In this mode, a target object manages all its dependent observer objects and actively notifies when its own state changes.
This is usually achieved by calling the methods provided by each observer.

When implementing the observer mode, it should be noted that the interaction between the observer and the observed object cannot be changed
It is embodied as a direct call between classes, otherwise it will closely couple the observer and the observed object,
It fundamentally violates the principle of object-oriented design. Whether the observer “observes” the observed object,
Or the observer “notifies” the observer of his changes, which should not be called directly.

Generally speaking, object a (observed) informs another (some) object (observer) of what has changed. As for what you objects want to do, it’s none of my business. Do it yourself! The coupling is reduced…

The following example implements the more traditional observer mode using Ruby’s module. The advantage of using module is that the subject class may be a subclass of other base classes, and mixin achieves the effect of similar multi inheritance.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
module Subject
 def initialize
  @observers = []
 end
 
 def add_observer ob
  @observers << ob
 end
 
 def delete_observer ob
  @observers.delete ob
 end
 
 def notify_observers
  @observers.each do |ob|
   ob.update self
  end
 end
end
 
class Employee
 include Subject
 attr_reader :name, :title
 attr_reader :salary
 
 def initialize name, title, salary
  super()
  @name = name
  @title = title
  @salary = salary
 end
 
 def salary=new_salary
  @salary = new_salary
  notify_observers
 end
end
 
class Taxman
 def update obj
  puts "#{obj.name} now has a salary of #{obj.salary}"
 end
end
 
jack = Employee.new('jack', 'prgramer', 3000)
jack.add_observer(Taxman.new)
jack.salary = 3000

We can implement the subject module ourselves, but this is a bit of icing on the cake, because the ruby core library itself contains the observable module, and we only need to mix its mixin code.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'observer'
 
class Employee
 include Observable
 
 attr_reader :name, :title, :salary
 
 def initialize name, title, salary
  @name = name
  @title = title
  @salary = salary
 end
 
 def salary=(new_salary)
  @salary = new_salary
  changed
  notify_observers(self)
 end # salary=
end # Employee

In notify_ The changed method must be called before observers to indicate that the change has indeed taken place, otherwise notify_ The observers method is invalid.