觀察者模式是什麼 觀察者模式是一種行為設計模式, 允許一個對象將其狀態的改變通知其他對象。觀察者模式允許你定義一種訂閱機制, 可在對象事件發生時通知多個觀察者。 為什麼用觀察者模式 當一個對象狀態改變時需要改變其他對象,可使用觀察者模式。它定義對象間的一對多的依賴關係,當一個對象的狀態發生改變時,所 ...
觀察者模式是什麼
觀察者模式是一種行為設計模式, 允許一個對象將其狀態的改變通知其他對象。觀察者模式允許你定義一種訂閱機制, 可在對象事件發生時通知多個觀察者。
為什麼用觀察者模式
當一個對象狀態改變時需要改變其他對象,可使用觀察者模式。它定義對象間的一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都會得到通知並被自動更新。
觀察者模式怎麼實現
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: "[email protected]"}
observerSecond := &customer{id: "[email protected]"}
shirtItem.register(observerFirst)
shirtItem.register(observerSecond)
shirtItem.updateAvailability()
}
優點
- 開閉原則。 你無需修改發佈者代碼就能引入新的訂閱者類 (如果是發佈者介面則可輕鬆引入發佈者類)。
- 你可以在運行時建立對象之間的聯繫
- 觀察者模式解除了主題和具體觀察者的耦合,讓耦合的雙方都依賴於抽象,而不是依賴具體。
缺點
- 訂閱者的通知順序是隨機的。