位置:首页 > Ruby > Ruby编程中观察者模式的运用实例与设计模式解析

Ruby编程中观察者模式的运用实例与设计模式解析

时间:2026-08-17  |  作者:宇宙开黑者  |  阅读:0

观察者模式——有时也叫发布/订阅模式——是软件设计模式中非常经典的一员。

简单来说,它定义了一种一对多的依赖关系:一个目标对象(被观察者)管理着所有依赖它的观察者对象。一旦自身状态发生改变,就会主动发出通知。

而这个通知,通常是通过调用观察者提供的接口方法来实现的。

设计模式中的观察者模式在Ruby编程中的运用实例解析

观察者模式的关键点

实现观察者模式时,有一个关键点容易被忽视:观察者和被观察对象之间的互动,绝不能体现成类之间的直接调用。

否则,两者就会紧密耦合,从根本上违背面向对象的设计原则。

无论是让观察者“观察”目标,还是让目标将其变化“通知”观察者,都不应该采用直接调用的方式。

换句大白话讲,A对象(被观察者)发现自己状态变了,就喊一声:“嘿,我变了!”

至于听到消息的那些观察者们要做什么,它一概不管,你们自己看着办。

正是这种“只通知不干预”的机制,才把耦合度降了下来。

Ruby 中的传统实现方式

下面用 Ruby 的模块实现一个比较传统的观察者模式。

使用模块的好处很明显:被观察的类可能已经是其他基类的子类了,通过 mixin 可以实现类似多继承的效果,灵活又干净。

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

这类实现的特点

  • 被观察者负责维护观察者列表。
  • 状态变化后,统一通知所有观察者。
  • 观察者只需实现对应的更新接口即可。

使用 Ruby 自带的 Observable 模块

当然,我们完全可以自己手写一个 Subject 模块,但说实话,这多少有点“重复造轮子”的味道。

因为 Ruby 核心库本身就自带了一个 Observable 模块,直接把它 mixin 进来就行,省时省力。

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

使用时需要注意的细节

需要注意一个细节:在调用 notify_observers 之前,必须先调用 changed 方法,表明状态确实发生了变更。

否则 notify_observers 调用是无效的。

这个机制看似多了一步,实际上给开发者留出了更精细的控制空间。

这样可以避免无效的重复通知。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多