ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 28.观察者模式 面向对象编程是根据现实世界建模的。 这里,对象需要彼此通信,其他对象需要在一个对象状态改变时做出反应。 假设你遇到一种情况,即对象的状态更改需要传播到 n 个其他对象,这些其他对象称为观察者。 当事情发生变化时,如何编写整洁的代码来通知观察者? 欢迎使用观察者模式。 看一下 [rator.rb](code/design_patterns/observer.rb) ,代码清单如下所示 ```rb ``` 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 ```rb | ``` # observer.rb class Person attr_accessor :name, :status, :observers def initialize name @name = name @observers =[] end def set_status status @status = status notify_observers end def notify_observers for observer in observers observer.notify self end end def notify person puts "#{person.name}: #{person.status} - notified to #{@name}" end end vel = Person.new "Vel" vel.observers &lt;&lt; Person.new("Murugan") vel.observers &lt;&lt; Person.new("Swami") vel.set_status "Hello All!" ```rb | ``` 在上面的代码中看看这些行 ```rb vel = Person.new "Vel" vel.observers << Person.new("Murugan") vel.observers << Person.new("Swami") ``` 因此,从上面的代码中我们知道,有一个名叫 Vel 的人被 Murugan 和 Swami 观察到。 想象一下一个社交网络,Vel 之后是 Murugan 和 Swami。 因此,我们在`Person`中有一个称为`observers`的属性,它不过是一个可以容纳尽可能多观察者的数组。 如果查看 [Observer.rb](code/design_patterns/observer.rb) ,你会注意到它已在以下几行中完成 ```rb class Person attr_accessor :name, :status, :observers def initialize name @name = name @observers =[] end ... end ``` 接下来看这条线 ```rb vel.set_status "Hello All!" ``` 在其中,我们设置 Vel 的状态。 运行程序时,将得到以下输出: ```rb Vel: Hello All! - notified to Murugan Vel: Hello All! - notified to Swami ``` 因此,你可以看到观察者已收到有关 Vel 的新状态的通知。 如何完成的? 如果查看 [viewer.rb](code/design_patterns/observer.rb) ,则在方法`set_status`中我们将调用方法`notify_observers`,在其中发生了魔术。 看看`notify_observers`方法 ```rb class Person ... def notify_observers for observer in observers**(1)** observer.notify self**(2)** end end ... end ``` 在其中发生以下情况 | **1** | 我们遍历每个观察者。 | | **2** | 我们在观察者中调用`notify`方法并传递更改后的对象。 | 由于观察者都是`Person`类型的,所以我们在与`notify`方法相同的类中编写了代码,请看下面的代码。 在里面 ```rb class Person ... def notify person**(1)** puts "#{person.name}: #{person.status} - notified to #{@name}"**(2)** end end ``` | **1** | `notify`接收更改的对象,在这种情况下为`person`。 | | **2** | 它对更改后的对象有作用。 | 这就是观察者模式的工作方式。 我们有存储观察者的方法,有一个通知观察者的方法,当需要进行通知时会调用该方法,最后我们有一个方法是观察者来接收更改的对象。 观察者可以对更改后的对象执行其希望的操作。 | | 实际上,当你使用 Ruby 时,观察者模式会直接放入其标准库中。 看看这个 https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html |