【问题标题】:Observer pattern - race condition观察者模式 - 竞争条件
【发布时间】:2015-04-26 16:01:36
【问题描述】:

对于我在 C++ 中的 OO 应用程序中发现的以下用法,我想听听您的意见,以及您认为它是正确的还是坏的。 我们使用观察模式来实现模型-视图-控制器如下:

 (Subject) (notify) (Listeners) 
 controller    --->  DB
               --->  Viewer

依赖DB首先注册到控制器(在查看器之前)并因此将在查看器之前更新的事实是否正确。这很关键,因为当查看器收到通知时,它会从 DB 中读取信息(因为它假定 DB 已经更新)。

编辑: controller 和 Viewer 是线程,而 DB 不是。 控制器总是先通知 DB,然后才通知 Viewer。 该应用程序正常工作。 我只是觉得在 Viewer 之前注册 DB 很丑,想请教一下。

谢谢,

【问题讨论】:

    标签: c++ oop design-patterns object-oriented-analysis


    【解决方案1】:

    我会建议另一种解决此问题的方法,因为您的数据库访问层具有此处所需的挂钩。

    情况分析: 鉴于数据库更新可能会失败,您的视图可能会执行不需要的更新。如果您有一个分布式应用程序,这可能会导致严重的性能问题。

    接下来的事情是:您的数据库更新可能需要比视图通知更长的时间,以便视图在更新时读取旧数据。 (认为​​这就是你所看到的竞争条件)。

    解决方案: 在您的数据库访问层上放置一个类似CommitFinished 的钩子以更新视图。

    因此,一种更稳健的方法是:

    1) 更改 => 控制器 => 数据库

    2) 数据库提交完成(一些 DataChanged 挂钩会做)=> 控制器 => 视图

    【讨论】:

    • 嗨,谢谢,我已经编辑了这个问题。实际上没有失败,只是我认为它可能不是“好”,因为DB必须在查看器之前注册。
    • 我认为你是对的。这种隐含的执行顺序(仅由注册顺序给出)是“丑陋的”。它会带来错误,也会带来错误。如果不是现在,那么在其他开发人员获取您的代码并且必须进行更改的时候。使其明确,因此在数据库更改后通知视图。不是因为注册顺序,而是因为数据库变化引起的某种事件。
    • 感谢您的建议!
    • 作为观察者的视图应该在其主题发生变化时得到通知。如果视图的主题是数据库中的数据,控制器不应通知视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 2019-03-20
    • 2016-02-20
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多