行为型:一. 观察者模式
观察者模式是什么
观察者模式是一种行为设计模式, 允许一个对象将其状态的改变通知其他对象。观察者模式允许你定义一种订阅机制, 可在对象事件发生时通知多个观察者。
为什么用观察者模式
当一个对象状态改变时需要改变其他对象,可使用观察者模式。它定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。
观察者模式怎么实现
subject.go是主体,sbserver.go是观察者。当item的对象发生变化的时候就会通知多个customer观察者。
subject.go
package observer
import "fmt"
type subject interface {
register(Observer observer)
deregister(Observer observer)
notifyAll()
}
type item struct {
observerList []observer
name string
inStock bool
}
func newItem(name string) *item {
return &item{
name: name,
}
}
func (i *item) updateAvailability() {
fmt.Printf("Item %s is now in stock\n", i.name)
i.inStock = true
i.notifyAll()
}
func (i *item) register(o observer) {
i.observerList = append(i.observerList, o)
}
func (i *item) deregister(o observer) {
i.observerList = removeFromslice(i.observerList, o)
}
func (i *item) notifyAll() {
for _, observer := range i.observerList {
observer.update(i.name)
}
}
func removeFromslice(observerList []observer, observerToRemove observer) []observer {
observerListLength := len(observerList)
for i, observer := range observerList {
if observerToRemove.getID() == observer.getID() {
observerList[observerListLength-1], observerList[i] = observerList[i], observerList[observerListLength-1]
return observerList[:observerListLength-1]
}
}
return observerList
}
observer.go
package observer
import "fmt"
type observer interface {
update(string)
getID() string
}
type customer struct {
id string
}
func (c *customer) update(itemName string) {
fmt.Printf("Sending email to customer %s for item %s\n", c.id, itemName)
}
func (c *customer) getID() string {
return c.id
}
客户端调用
func Example() {
shirtItem := newItem("Nike Shirt")
observerFirst := &customer{id: "abc@gmail.com"}
observerSecond := &customer{id: "xyz@gmail.com"}
shirtItem.register(observerFirst)
shirtItem.register(observerSecond)
shirtItem.updateAvailability()
}
优点
- 开闭原则。 你无需修改发布者代码就能引入新的订阅者类 (如果是发布者接口则可轻松引入发布者类)。
- 你可以在运行时建立对象之间的联系
- 观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。
缺点
- 订阅者的通知顺序是随机的。