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.