MST
星途 面试题库

面试题:Ruby中观察者模式在事件驱动系统中的应用

在一个基于Ruby的事件驱动系统中,有多个事件源(如用户登录、文件上传等),需要多个不同的观察者(如记录日志、更新统计数据等)对这些事件做出响应。请设计并实现这种基于观察者模式的架构,说明如何注册观察者、触发事件以及解注册观察者。
32.3万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试

1. 设计思路

在Ruby中实现观察者模式,我们可以定义一个Subject类来表示事件源,一个Observer接口(在Ruby中通过模块实现)来表示观察者,具体的观察者类混入该模块。Subject类维护一个观察者列表,提供注册、解注册和触发事件的方法。

2. 代码实现

# 定义Observer模块
module Observer
  def update(event)
    raise NotImplementedError, "Subclasses must implement update method"
  end
end

# 定义Subject类
class Subject
  def initialize
    @observers = []
  end

  # 注册观察者
  def register_observer(observer)
    @observers << observer if observer.is_a?(Class.new.extend(Observer))
  end

  # 解注册观察者
  def unregister_observer(observer)
    @observers.delete(observer)
  end

  # 触发事件
  def notify_observers(event)
    @observers.each { |observer| observer.update(event) }
  end
end

# 具体的观察者类,例如记录日志
class LoggerObserver
  include Observer
  def update(event)
    puts "Logging event: #{event}"
  end
end

# 具体的观察者类,例如更新统计数据
class StatisticObserver
  include Observer
  def update(event)
    puts "Updating statistics for event: #{event}"
  end
end

3. 使用示例

# 创建Subject实例
subject = Subject.new

# 创建观察者实例
logger = LoggerObserver.new
statistic = StatisticObserver.new

# 注册观察者
subject.register_observer(logger)
subject.register_observer(statistic)

# 触发事件
subject.notify_observers("User logged in")

# 解注册观察者
subject.unregister_observer(logger)

# 再次触发事件
subject.notify_observers("File uploaded")

4. 说明

  • 注册观察者Subject类的register_observer方法接收一个实现了Observer模块的观察者对象,并将其添加到观察者列表@observers中。
  • 触发事件Subject类的notify_observers方法遍历观察者列表,调用每个观察者的update方法,并传入事件相关信息。
  • 解注册观察者Subject类的unregister_observer方法从观察者列表中移除指定的观察者对象。