Autumn SALE
观察者

Ruby 观察者模式讲解和代码示例

观察者是一种行为设计模式 允许一个对象将其状态的改变通知其他对象

观察者模式提供了一种作用于任何实现了订阅者接口的对象的机制 可对其事件进行订阅和取消订阅

复杂度

流行度

使用示例 观察者模式在 Ruby 代码中很常见 特别是在 GUI 组件中 它提供了在不与其他对象所属类耦合的情况下对其事件做出反应的方式

识别方法 该模式可以通过将对象存储在列表中的订阅方法 和对于面向该列表中对象的更新方法的调用来识别

概念示例

本例说明了观察者设计模式的结构并重点回答了下面的问题

  • 它由哪些类组成
  • 这些类扮演了哪些角色
  • 模式中的各个元素会以何种方式相互关联

main.rb: 概念示例

# The Subject interface declares a set of methods for managing subscribers. class Subject # Attach an observer to the subject. def attach(observer) raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end # Detach an observer from the subject. def detach(observer) raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end # Notify all observers about an event. def notify raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end # The Subject owns some important state and notifies observers when the state # changes. class ConcreteSubject < Subject # For the sake of simplicity, the Subject's state, essential to all # subscribers, is stored in this variable. attr_accessor :state # @!attribute observers # @return [Array<Observer>] attr_accessor :observers private :observers def initialize @observers = [] end # List of subscribers. In real life, the list of subscribers can be stored # more comprehensively (categorized by event type, etc.). # @param [Observer] observer def attach(observer) puts 'Subject: Attached an observer.' @observers << observer end # @param [Observer] observer def detach(observer) @observers.delete(observer) end # The subscription management methods. # Trigger an update in each subscriber. def notify puts 'Subject: Notifying observers...' @observers.each { |observer| observer.update(self) } end # Usually, the subscription logic is only a fraction of what a Subject can # really do. Subjects commonly hold some important business logic, that # triggers a notification method whenever something important is about to # happen (or after it). def some_business_logic puts "\nSubject: I'm doing something important." @state = rand(0..10) puts "Subject: My state has just changed to: #{@state}" notify end end # The Observer interface declares the update method, used by subjects. class Observer # Receive update from subject. def update(_subject) raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end # Concrete Observers react to the updates issued by the Subject they had been # attached to. class ConcreteObserverA < Observer # @param [Subject] subject def update(subject) puts 'ConcreteObserverA: Reacted to the event' if subject.state < 3 end end class ConcreteObserverB < Observer # @param [Subject] subject def update(subject) return unless subject.state.zero? || subject.state >= 2 puts 'ConcreteObserverB: Reacted to the event' end end # The client code. subject = ConcreteSubject.new observer_a = ConcreteObserverA.new subject.attach(observer_a) observer_b = ConcreteObserverB.new subject.attach(observer_b) subject.some_business_logic subject.some_business_logic subject.detach(observer_a) subject.some_business_logic 

output.txt: 执行结果

Subject: Attached an observer. Subject: Attached an observer. Subject: I'm doing something important. Subject: My state has just changed to: 1 Subject: Notifying observers... ConcreteObserverA: Reacted to the event Subject: I'm doing something important. Subject: My state has just changed to: 10 Subject: Notifying observers... ConcreteObserverB: Reacted to the event Subject: I'm doing something important. Subject: My state has just changed to: 2 Subject: Notifying observers... ConcreteObserverB: Reacted to the event 

观察者在其他编程语言中的实现

C# 观察者模式讲解和代码示例 C++ 观察者模式讲解和代码示例 Go 观察者模式讲解和代码示例 Java 观察者模式讲解和代码示例 PHP 观察者模式讲解和代码示例 Python 观察者模式讲解和代码示例 Rust 观察者模式讲解和代码示例 Swift 观察者模式讲解和代码示例 TypeScript 观察者模式讲解和代码示例