什么是观察者设计模式?Golang中的观察者模式介绍

当涉及到订单处理系统时,观察者设计模式可以用于实现订单状态的变化和通知。在这篇文章中,我们将介绍如何使用golang来实现观察者设计模式,并提供一个基于订单处理系统的代码示例。
什么是观察者设计模式?
观察者设计模式是一种行为型设计模式,它允许对象之间的松耦合通信。在这种模式中,一个对象(称为主题subject)维护一组依赖于它的对象(称为观察者observer)的列表,并在状态改变时自动通知它们。观察者模式可以用于实现事件驱动的系统,其中对象之间的交互是通过事件的发布和订阅来完成的。
应用场景:订单处理系统
在订单处理系统中,订单的状态可能会发生变化,例如创建、支付、发货、取消等。当订单状态发生变化时,我们希望通知相关的观察者进行相应的处理,例如更新库存、发送通知等。
实现观察者设计模式
在golang中,可以使用channel和goroutine来实现观察者设计模式。
首先,我们定义一个订单结构体,包含订单的基本信息和状态:
type order struct { id string status string}然后,我们定义一个观察者接口,包含一个update方法,用于处理订单状态变化的通知:type observer interface { update(order *order, wg *sync.waitgroup)}  
接下来,我们定义一个主题结构体,使用channel和goroutine来通知观察者:
type subject struct { observers []observer}func (s *subject) register(observer observer) { s.observers = append(s.observers, observer)}func (s *subject) notify(order *order) { wg := sync.waitgroup{} wg.add(len(s.observers)) errch := make(chan error, len(s.observers)) for _, observer := range s.observers { go func(obs observer) { defer wg.done() err := obs.update(order, &wg) if err != nil { errch <- err } }(observer) } wg.wait() close(errch) // 处理异常 for err := range errch { fmt.println(error occurred:, err) }}  
我们首先创建了一个errch(类型为chan error)来接收观察者处理过程中可能发生的异常。然后,在每个观察者的goroutine中,我们通过闭包的方式传递observer并在处理完成后检查是否有异常发生。如果有异常,我们将其发送到errch中。
在notify方法的最后,我们关闭了errch通道,并通过range循环来处理所有的异常。
接下来,我们实现两个观察者:库存观察者和通知观察者。
库存观察者用于更新库存状态:
type inventoryobserver struct{}func (io *inventoryobserver) update(order *order, wg *sync.waitgroup) { defer wg.done() // 更新库存状态 fmt.printf(inventory observer: order %s status changed to %s, order.id, order.status)}  
通知观察者用于发送通知:
type notificationobserver struct{}func (no *notificationobserver) update(order *order, wg *sync.waitgroup) { defer wg.done() // 发送通知 fmt.printf(notification observer: order %s status changed to %s, order.id, order.status)}  
最后,我们在主函数中使用观察者模式来处理订单状态变化的通知:
func main() { order := &order{ id: 123, status: created, } subject := &subject{} subject.register(&inventoryobserver{}) subject.register(¬ificationobserver{}) // 模拟订单状态变化 order.status = paid subject.notify(order) order.status = shipped subject.notify(order)}  
我们创建了一个订单对象和一个主题对象,并注册了库存观察者。然后,我们模拟订单状态的变化,通过调用notify方法并发地通知观察者进行处理。
通过使用channel和goroutine,我们可以实现观察者模式的并发处理,提高系统的性能和响应能力。
使用观察者设计模式的一些优点
松耦合:观察者模式可以将观察者和主题(或被观察者)对象解耦。观察者只需要关注主题的状态变化,而不需要了解具体的实现细节。这样可以使得系统更加灵活和可扩展。
可重用性:通过将观察者和主题对象分离,可以使得它们可以在不同的上下文中重复使用。例如,可以在不同的业务场景中使用相同的观察者来处理不同的主题对象。
易于扩展:当需要添加新的观察者或主题时,观察者模式可以很方便地进行扩展。只需要实现新的观察者或主题对象,并注册到主题对象中即可。
事件驱动:观察者模式适用于事件驱动的系统。当主题对象的状态发生变化时,可以通过触发事件来通知所有的观察者进行相应的处理。
如果不使用观察者设计模式
订单业务可能会以一种更加紧耦合的方式实现。以下是一个示例代码,展示了在没有使用观察者模式的情况下,如何处理订单状态变化的问题:
type order struct { id string status string}type orderprocessor struct { inventoryobserver *inventoryobserver notificationobserver *notificationobserver}func neworderprocessor() *orderprocessor { return &orderprocessor{ inventoryobserver: &inventoryobserver{}, notificationobserver: ¬ificationobserver{}, }}func (op *orderprocessor) process(order *order) { // 更新库存 op.inventoryobserver.update(order) // 发送通知 op.notificationobserver.update(order)}func main() { order := &order{ id: 123, status: created, } op := neworderprocessor() // 模拟订单状态变化 order.status = paid op.process(order) order.status = shipped op.process(order)}  
在这个示例中,orderprocessor对象负责处理订单状态变化。它内部包含了inventoryobserver和notificationobserver对象,并在process方法中依次调用它们的update方法来处理订单状态变化。
这种实现方式存在一些问题:
紧耦合:orderprocessor对象直接依赖于inventoryobserver和notificationobserver对象。如果需要添加或删除其他观察者,需要修改orderprocessor的代码,导致代码的可维护性和可扩展性下降。
代码重复:每当有新的观察者需要处理订单状态变化时,都需要在orderprocessor中添加相应的代码。这样会导致代码的重复和冗余。
可扩展性差:在没有使用观察者模式的情况下,很难在系统中添加新的观察者,因为每次都需要修改orderprocessor的代码。


华为nova2新机发布是针对美拍市场,OPPOR11如何立足?
台湾厂商如何看待中美贸易战
今天小米发布红米note4x ,魅族会揭露什么真像?
刚性电路板的特点及与柔性电路板的区别
iPhone13发售 三里屯苹果店外顾客冒雨排队
什么是观察者设计模式?Golang中的观察者模式介绍
全自动焊接机出现焊点飞溅的原因及解决方法
微软的Azure数据共享使大数据共享更容易更安全
三星利润暴跌,铠侠西数重启合并,这个存储市场冷冰冰
GAD7980(替代AD7980)在血压检测仪中的应用方案
RRAM的研究进展 RRAM的四大发展机遇
魅蓝X怎么样?魅蓝X评测:双面玻璃+夏普屏+联发科P20,这款魅蓝旗舰已经降至冰点价
小熊电器未来高增速发展或难以保持
明年国产手机涨价,魅族先涨了!
基于can总线技术的电子控制系统单元在汽车网络系统中的应用
每日一课 | 智慧灯杆工程设计通信网络之传输光缆
NVIDIA Morpheus AI安全框架构建解决方案
twimbit推出智能工具Ask twimbit
AMD正式发布锐龙5000系列移动处理器
CRT显示器画面不正常分析