ruby和javascript的观察者模式
观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。
在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。
这通常透过呼叫各观察者所提供的方法来实现。
实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。
无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。
观察者模式在ruby中的是实现
1 module Subject 2 3 # 初始化一个存放观察者的数组 4 def initialize 5 puts "subject initialize.." 6 @observers = [] 7 end 8 9 # 将观察者塞入该数组(在本文中,这些观察者实际上是一个实例化的类) 10 def add_observer ob 11 @observers << ob 12 end 13 14 # 将观察者从数组中删除 15 def delete_observer ob 16 @observers.delete ob 17 end 18 19 # 通知观察者 20 # 1.遍历数组中所有的观察者 21 # 2.执行该观察者的update方法, 将self作为参数传递,这里的self是被观察者(被观察者类的是实例化) 22 def notify_observers 23 @observers.each do |ob| 24 ob.update self 25 end 26 end 27 end 28 29 # 被观察者 30 class Employee 31 include Subject 32 attr_reader :name, :title 33 attr_reader :salary 34 35 def initialize name, title, salary 36 super() 37 puts "Employee initialize.." 38 @name = name 39 @title = title 40 @salary = salary 41 end 42 43 # 调用salary=的时候通知观察者 44 def salary=new_salary 45 @salary = new_salary 46 notify_observers 47 end 48 end 49 50 # 观察者 51 class Taxman 52 def update obj 53 puts "Taxman: #{obj.name} now has a salary of #{obj.salary}" 54 end 55 end 56 57 # 观察者 58 class Employer 59 def update obj 60 puts "Employer: #{obj.name} now has a salary of #{obj.salary}" 61 end 62 end 63 64 jack = Employee.new('jack', 'prgramer', 3000) 65 jack.add_observer(Taxman.new) 66 jack.add_observer(Employer.new) 67 jack.salary = 3001 68 jack.salary = 3002
实现的思路就是: 用一个notify_observers将观察者和被观察者联系起来
观察者模式在javascript中的是实现
1 // 被观察者 2 var observer = { 3 //订阅 增加一个观察者, 4 addSubscriber: function (callback) { 5 this.subscribers[this.subscribers.length] = callback; 6 }, 7 //退订 删除一个观察者, 8 removeSubscriber: function (callback) { 9 for (var i = 0; i < this.subscribers.length; i++) { 10 if (this.subscribers[i] === callback) { 11 delete (this.subscribers[i]); 12 } 13 } 14 }, 15 //发布 被观察者发生变化,发布了一个消息 16 publish: function (what) { 17 for (var i = 0; i < this.subscribers.length; i++) { 18 if (typeof this.subscribers[i] === 'function') { 19 alert(this.subscribers[i]) 20 this.subscribers[i](what); 21 } 22 } 23 }, 24 // 将对象o具有观察者功能 25 make: function (o) { 26 for (var i in this) { 27 o[i] = this[i]; 28 o.subscribers = []; 29 } 30 } 31 }; 32 33 var blogger = { 34 recommend: function (id) { 35 var msg = 'dudu 推荐了的帖子:' + id; 36 this.publish(msg); 37 } 38 }; 39 40 var user = { 41 vote: function (id) { 42 var msg = '有人投票了!ID=' + id; 43 this.publish(msg); 44 } 45 }; 46 47 observer.make(blogger); 48 observer.make(user); 49 50 // 观察者 51 var tom = { 52 read: function (what) { 53 console.log('Tom看到了如下信息:' + what) 54 } 55 }; 56 57 var mm = { 58 show: function (what) { 59 console.log('mm看到了如下信息:' + what) 60 } 61 }; 62 // 订阅 63 blogger.addSubscriber(tom.read); 64 blogger.addSubscriber(mm.show); 65 blogger.recommend(123); //调用发布 66 67 // 退订 68 blogger.removeSubscriber(mm.show); 69 blogger.recommend(456); //调用发布 70 71 // 另外一个对象的订阅 72 user.addSubscriber(mm.show); 73 user.vote(789); //调用发布