简介
观察者模式是一种行为设计模式,目的在于定义一种订阅机制,在对象事件发生时通知“观察”该对象的对象。例如:商店和顾客,顾客要购买新款手机但未到货,顾客在商店进行了订阅,只要商店新款手机到货,就立即发送短信通知顾客。这里顾客是观察者(Observer),商店被观察者(subject)。
类图模式
对应类图可用如下表示:
该设计模式共有四类角色:
1、抽象主题(Subject):该角色可以增加或者删除观察者对象。
2、具体发布者(ConcreteSubject):会向其他Observer对象发送值得关注的事件(自身状态发生改变)。发布者中包含一个允许新订阅者加入和当前订阅者离开list的订阅框架。
3、订阅者(Observer):该接口声明了通知接口。该接口仅包含一个 update 更新方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。
4、具体订阅者(Observer1…ObserverN): 实现了订阅者接口的类,都需要实现update方法,具体发布者可以调用这些Observer的update方法进行更新。
实例代码
package main
import "fmt"
// The customer interface
type interfaceCustomer interface {
Update(phoneName string)
}
// The class of customer
type CustomerALL struct {
phoneName string
}
func (C *CustomerALL) Update(phoneName string) {
fmt.Println(C.phoneName, "-Get the Phone", phoneName)
}
// The market interface
type interfaceMarket interface {
Attach(customer interfaceCustomer)
Dettach(customer interfaceCustomer)
NotifyObservers(phoneName string)
}
// The concrete class of market
type MarketA struct {
list []interfaceCustomer
}
func (m *MarketA) Attach(customer interfaceCustomer) {
// Add some customers
m.list = append(m.list, customer)
}
func (m *MarketA) Dettach(customer interfaceCustomer) {
// Delete customer
for i, value := range m.list {
if value == customer {
//delete the customer
m.list = append(m.list[:i], m.list[i+1:]...)
}
}
}
func (m *MarketA) NotifyObservers(phoneName string) {
// Notify all customers that the market have the phone now!
for _, customer := range m.list {
customer.Update(phoneName)
}
}
func (m *MarketA) Change (phoneName string) {
m.NotifyObservers(phoneName)
}
func main() {
// create a Market
market := MarketA{list: []interfaceCustomer{}}
// create customerA
customerA := CustomerALL{phoneName:"A"}
// customerA subscribe the notify from Market
market.Attach(&customerA)
// create customerB
customerB := CustomerALL{phoneName:"B"}
// customerB subscribe the notify from Market
market.Attach(&customerB)
// The market have new phone now
market.Change("New Phone")
fmt.Println("Customer B fire the subscribe!")
market.Dettach(&customerB)
market.Change("New Phone Plus")
}
运行结果如下所示:
A -Get the Phone New Phone
B -Get the Phone New Phone
Customer B fire the subscribe!
A -Get the Phone New Phone Plus
总结
该模式的优点:被观察者和观察者之间实现了抽象耦合,容易扩展。广播模式,只要订阅,就能收到消息。
该模式的缺点:观察者收到变化,不知道什么时候发生的变化,轮询通知观察者,比较耗时。