Behavior type: I Observer mode

Time:2022-5-22

What is the observer mode

Observer pattern is a behavior design pattern that allows one object to notify other objects of changes in its state. Observer mode allows you to define a subscription mechanism that can notify multiple observers when an object event occurs.

Why use observer mode

When the state of one object changes and other objects need to be changed, observer mode can be used. It defines one to many dependencies between objects. When the state of an object changes, all objects that depend on it will be notified and updated automatically.

How is observer mode implemented

subject. Go is the main body, sbserver Go is the observer. When the object of item changes, multiple customer observers will be notified.

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
}

Client call

func Example() {

    shirtItem := newItem("Nike Shirt")

    observerFirst := &customer{id: "[email protected]"}
    observerSecond := &customer{id: "[email protected]"}

    shirtItem.register(observerFirst)
    shirtItem.register(observerSecond)

    shirtItem.updateAvailability()
}

advantage

  1. Opening and closing principle. You can introduce new subscriber classes without modifying the publisher code (publisher classes can be easily introduced if it is a publisher interface).
  2. You can establish connections between objects at run time
  3. The observer pattern decouples the subject from the concrete observer, so that both sides of the coupling rely on abstraction rather than concrete.

shortcoming

  1. The order of notification for subscribers is random.

Recommended Today

Leetcode PHP题解–D127 455. Assign Cookies

D127 455. Assign Cookies topic link 455. Assign Cookies topic analysis Given two arrays, the first array represents the capacity of each container, and the second array represents the number of each item. The items need to be stuffed into the container, but there are two conditions. Condition 1: Only one item can be stuffed […]