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); //调用发布

 




posted @ 2015-02-27 09:23  耿小曾  阅读(208)  评论(0编辑  收藏  举报