设计模式(观察者模式)

一、应用

1.1 概念

观察者设计模式是一种行为设计模式,它会允许你自定义你自己想要的订阅机制,
这个订阅机制主要是用于对象发生某些事件时能够通知多个该对象的其他对象。

这句话可能听起来有些绕口,不过我们不慌,让我们看下1.2然后在反过来看这句话,相信以你的理解能力能够瞬间融会贯通!

1.2 应用设计

让我们来举一个栗子:
假如某家报社在发布某版报纸的时候只想发给某些想看到的人:

非观察者模式:
这家报社采用大量的人力、财力挨家挨户发送该报纸,我们不妨假设情况会像下面一样:
非观察者模式
我们可以轻易的发现,当这家报社给所有人发出报纸后只有一家反馈了比较好的看法,其他三家可能后续对这家报社的感官直接变差。

但是我们采用观察者模式会发生什么呢?

观察者模式
这家报社将报纸提供给中间商,这个中间商会看是谁关注了这个报纸,他会将该报纸只发给关注这个的人,图如下所示:
观察者模式
通过这个中间商,我们会在报纸出来之后发给订阅该报纸的人,而不全部发送。其实通过这两张图我们就能够轻松的发现观察者模式的用处。

1.3 模式结构

观察者模式简易类图

二、实现

2.1 Python实现

from random import randrange
from abc import ABC, abstractmethod


class Send(object):
    _have = None
    _observers = list()

    def subscribe(self, observers):
        """
        模拟订阅的情况
        """
        if observers not in self._observers:
            self._observers.append(observers)

    def unsubscribe(self, observers):
        """
        模拟取消订阅的情况
        """
        if observers in self._observers:
            self._observers.remove(observers)

    def notice(self):
        """
        模拟通知的情况
        """
        for obs in self._observers:
            obs.is_send(self)

    def some_logic(self):
        """
        模仿一些业务逻辑,这里主要采用对象本身的update属性进行操作
        """
        self._have = randrange(0, 100)
        self.notice()


class Observers(ABC):
    @abstractmethod
    def is_send(self):
        pass


class ObserversA(Observers):
    def is_send(self, send_attr):
        """
        模拟满足条件发送
        """
        if send_attr._have < 50:
            print("A")


class ObserversB(Observers):
    def is_send(self, send_attr):
        """
        模拟满足条件发送
        """
        if send_attr._have >= 50:
            print("B")


if __name__ == '__main__':
    send = Send()

    obs_a = ObserversA()

    send.subscribe(obs_a)

    obs_b = ObserversB()

    send.subscribe(obs_b)

    send.some_logic()
    send.some_logic()

2.2 Java实现

2.3 Golang实现

2.3.1 item.go 具体主体

package main

import "fmt"

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
}

2.3.2 item_main.go 主体

package main

import "fmt"

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
}

2.3.3 obs.go 观察者

package main

type Observer interface {
	update(string)
	getID() string
}

2.3.4 cus.go 具体观察者

package main

import "fmt"

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
}

2.3.5 main.go 运行

package main

func main() {

	shirtItem := newItem("Nike Shirt")

	observerFirst := &Customer{id: "123456@qq.com"}
	observerSecond := &Customer{id: "78910@qq.com"}

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

	shirtItem.updateAvailability()
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值