观察者模式的应用

最近想到一种电商中需求:用户可以关注某件商品,当该商品有降价或打折等促销活动的时候通知关注该商品的用户

这里有点类似于微博中关注某用户后,可以获取被专注用户的消息动态

这里我觉得可以用观察者模式来实现消息的传递

简化Demo代码如下

  1 # encoding: utf-8
  2
  3 # 有三个角色 ("商品","买家","卖家")
  4 # 1.买家关注商品后商品出现价格变动的时候通知该买家
  5 # 2.买家可以设置当某个商品降价到一定程度的时候通知该买家
  6 # 3.卖家可以知道有多少人关注该商品
  7
  8 # 通过数据库的实现方式
  9 # 1.新建五张张表,商品表,买家表(Buyers),卖家表,订阅发布表(Sub_pubs),消息表(Messages)(买家表和卖家表合意用一张用户表)
 10 # 2.当买家关注一个商品的时候向订阅发布表中写数据:(加入resource字段可以更好的适应可能出现的新的需求,例如:买家关注卖家后,买家可以得知卖家的一切动态等等)
 11 # {:pub_resource => ‘product‘,
 12 #  :publisher_id => product.id,
 13 #  :sub_resource => ‘buyer‘,
 14 #  :subscriber_id => buyer.id,
 15 #  :action => func}
 16 # 3.当商品价格变动后通过订阅发布表想消息表中写数据:
 17 # {:user_id => buyer.id,
 18 #  :message => ‘some text‘
 19 #  :state => 0}
 20
 21 # ‘notify_observer‘将类似于这样
 22 def notify_observer # 不考虑高并发的情况
 23   Sub_pubs.where(id: self.id).each do |sub_pub|
 24     some_text = sub_pub.pub_resource.send(sub_pub.action, self)
 25     Message.create!(user_id: sub_pub.subscriber_id,
 26                     message: some_text.to_s,
 27                     state: 0)
 28   end
 29 end
 30
 31
 32 module Subject
 33   def initialize
 34     @observers = []
 35   end
 36
 37   def add_observer ob
 38     unless @observers.include?(ob)
 39       @observers << ob
 40     end
 41   end
 42
 43   def delete_observer ob
 44     @observers.delete ob
 45   end
 46
 47   # 修改点1, 将发布消息调用的函数通过参数接收过来, 或者通过method_missing
 48   # 通知设置提醒的买家
 49   def notify_observer(func)
 50     @observers.each do |ob|
 51       if ob.state == 0
 52         ob.send(func, self)
 53       end
 54     end
 55   end
 56
 57   def notify_remind_observer(func)
 58     @observers.each do |ob|
 59       if ob.state == 1
 60         ob.send(func, self)
 61       end
 62     end
 63   end
 64
 65 end
 66
 67 # 商品类
 68 class Product
 69   include Subject
 70   attr_reader :owner, :name, :price, :old_price
 71
 72   def initialize(owner, name, price, discount)
 73     super()
 74     @owner = owner
 75     @name = name
 76     @price = price
 77     @old_price = ‘‘
 78   end
 79
 80   # 价格变动时发出通知:
 81   def price= new_price
 82     if @price != new_price
 83
 84       old_price = @price.to_i
 85       @price = new_price
 86       @old_price = old_price
 87
 88       @observers.each do |ob|
 89         if ob.remind_price >= new_price
 90           ob.state = 1
 91           notify_remind_observer(:remind_price_ok)
 92         end
 93       end
 94
 95       if new_price < old_price
 96         # notify_observers_down_price
 97         notify_observer(:down_price)
 98         # 商品降价
 99       else
100         notify_observer(:up_price)
101         # 商品涨价
102       end
103
104     end
105
106   end
107
108   # 折扣变动时发出通知
109   def discount= new_discount
110     old_discount = @discount
111     if new_discount != new_discount
112       @discount = new_discount
113       notify_observers
114       if new_discount >= 8
115         # 八折以上
116       else
117         # 八折以下
118       end
119     end
120   end
121 end
122
123 # 管理类
124 module MethodManage
125   def down_price product
126     puts "#{product.owner.name}的#{product.name}提醒您: 商品降价了, 原价是 #{product.old_price},现价是 #{product.price}"
127   end
128
129   def up_price product
130     puts "#{product.owner.name}的#{product.name}提醒您: 商品涨价了, 原价是 #{product.old_price},现价是 #{product.price}"
131   end
132
133   def remind_price_ok product
134     puts "#{product.owner.name}的#{product.name}提醒您: 您可以购买#{product.name}了, 现价是 #{product.price}"
135   end
136 end
137
138 class Buyers
139   include MethodManage
140   attr_accessor :name, :remind_price, :state
141   def initialize(name)
142     @name = name
143     @remind_price = -1
144     @state = 0
145   end
146
147   # 关注商品后,商品价格发生变化通知购买者
148   def mark(resource)
149     @state = 0
150     resource.add_observer(self)
151     add_buyer(resource)
152   end
153
154   # 设置提醒,当价格到达一定程度通知购买者
155   def remind(resource, price)
156     @state = 2
157     @remind_price = price
158     resource.add_observer(self)
159     add_buyer(resource)
160   end
161
162   private
163   def add_buyer(product)
164     unless product.owner.buyers.include?(self)
165       product.owner.add_buyer(self)
166     end
167   end
168 end
169
170 class Sellers
171   attr_reader :name, :buyers
172   def initialize(name)
173     @name = name
174     @buyers = []
175   end
176
177   def add_buyer(buyer)
178     @buyers << buyer
179   end
180 end
181
182 seller_jack = Sellers.new("jack")
183 apple = Product.new(seller_jack, ‘Apple‘, ‘100‘, 1)
184 buyer_angel = Buyers.new(‘angel‘)
185 buyer_angel.mark(apple)
186 buyer_legend = Buyers.new(‘legend‘)
187 buyer_legend.remind(apple, 40)
188 apple.price = 101
189 apple.price = 30
190 p seller_jack.buyers
时间: 2024-10-12 08:29:24

观察者模式的应用的相关文章

观察者模式

观察者模式:一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现. 观察者 (Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(List)里. 被观察者 被观察对象(Subject)发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者. 代码实例: //被观察者接口 public interface Subject { void add(Observer observer

ExtJS要利用观察者模式 去实现自定义的事件

1 // 要利用观察者模式 去实现自定义的事件 2 3 4 //1:由于浏览器他自己能定义内置的事件(click/blur...) 5 // 我们也应该有一个类似于浏览器这样的类,这个类 自己去内部定义一些事件(自定义事件) 6 var Observable = function(){ 7 //承装自己所定义的事件类型的 8 this.events = ['start','stop']; 9 //我们应该设计一种数据类型,这种数据类型就可以去维护自定义事件类型 和 和相关绑定函数的关系,结构如下

【非凡程序员】 OC第十五节课 (观察者模式和KVO进行对比)

今天主要学了观察者模式,以及回顾复习了KVO,两者进行对比 什么是观察者模式? 我们先打个比方,这就像你订报纸.比如你想知道美国最近放生了些新闻,你可能会订阅一份美国周刊,然后一旦美国有了新的故事,美国周刊就发一刊,并邮寄给你,当你收到这份报刊,然后你就能够了解美国最新的动态.其实这就是观察者模式,A对B的变化感兴趣,就注册为B的观察者,当B发生变化时通知A,告知B发生了变化.这是一种非常典型的观察者的用法,我把这种使用方法叫做经典观察者模式 KVO的全称是Key-Value Observer,

php实现观察者模式

<meta charset='utf-8' /> <title>观察者模式</title> <?php class Tongzhi implements SPLSubject { protected $subs = array(); public $username = '我是被观察者'; public function __construct(){ } public function attach(SPLObserver $sub){ $this->sub

浅谈java中内置的观察者模式与动态代理的实现

一.关于观察者模式 1.将观察者与被观察者分离开来,当被观察者发生变化时,将通知所有观察者,观察者会根据这些变化做出对应的处理. 2.jdk里已经提供对应的Observer接口(观察者接口)与Observable(被观察者类)用于实现观察者模式 3.关于Observer接口,该接口只有一个update方法,当被观察者发生相关变化时,会通知所有的观察者,观察者接受到通知时,调用update方法进行处理.贴出源代码: 1 /* 2 * Copyright (c) 1994, 1998, Oracle

【设计模式】 观察者模式

1.定义 1.1 标准定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经常使用的模式,其定义如下:Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使

《JAVA与模式》之观察者模式

观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependents)模式. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观察者模式的结构 一个软件系统里面包含了各种对象,就像一片欣欣向荣的森林充满了各种生物一样.在一片森林中,各种生物彼此依赖和约束

设计模式之二:观察者模式(Observer Pattern)

先看下观察者模式的定义: The Observer Pattern defines a one-to-many denpendency between objects so that when one object changes state, all of its dependents are notified and updated automatically.:观察者模式定义了对象间一对多依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新. 观察者模式又叫发布-

设计模式之观察者模式

观察者模式又称发布-订阅模式,是一种行为型模式.在此种模式中,一个目标物件管理所有相依于它的观察者物件, 并且在它本身的状态改变时主动发出通知.这种模式通常用来实现事件处理系统. 观察者模式完美的将观察者和被观察的对象分离开,在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性. 观察者模式定义了对象间的一种一对多的依赖关系,以便一个对象状态发生变化时,所有依赖于它的对象都得到通知并自动刷新. 实现方式: 观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象.

用java观察者模式解耦经典三层架构

三层架构是一个很经典的架构模式,依据系统的职责不同.将系统分成了表现层,逻辑层和数据訪问层,而且配合数据实体进行传输数据,能够大大的封装性和复用性. 经典的三层架构图: 我们再深入到架构图内部.看看详细的类图,用简单的登陆举例吧: 这里通过LoginUI.调用了LoginLogService和LoginVerificationService两个类.通过类图能够看得出,U层和Service层(本文把BLL层称为了Service层)直接採用了直接调用的方式. 在面向对象的设计中.一直强调要面向接口编