最近想到一种电商中需求:用户可以关注某件商品,当该商品有降价或打折等促销活动的时候通知关注该商品的用户
这里有点类似于微博中关注某用户后,可以获取被专注用户的消息动态
这里我觉得可以用观察者模式来实现消息的传递
简化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