观察者模式和有状态的可观察范式

Observer pattern and stateful observable paradigm

在 Android 应用程序的开发过程中,我遇到了这个我目前无法解决的设计难题。如果有任何想法、解决方法或干净的解决方案,我将不胜感激 :) 我会尽量简化它:

一切都从一个通用的观察者模式实现开始。有一个主题在其 public 方法调用时改变状态;并且有观察者对这些变化做出相应的反应。 在这种情况下,主题是一个有状态的主题,这意味着它有一个内部状态控制器(一个 int),它像自动机一样变化。每次它的状态改变时,它都会像往常一样通知观察者:

但是现在想想这个情况:

作为第二个瀑布的结果,现在将要发生的是下一个观察者(假设观察者 B)将收到状态 Y 的通知(来自最后一个第二个瀑布),相应地采取行动,当这个第二个瀑布结束,PC(程序计数器)将继续第一个通知瀑布并重新通知观察者 B 旧状态 X。这会产生两个主要问题:第一个是观察者 B 以错误的顺序收到新状态的通知(第一个状态 Y然后在应该以相反的方式时声明 X),其次也是最重要的,即使以错误的顺序通知,当观察者 B 收到新状态 X 的通知时,它是完全错误的,因为主体真实状态是 Y;这会产生很多问题。

正如您可能已经意识到的那样,当观察者提交了主体状态的更改时,当它收到通知而不是仅从主体获取数据时,就会发生这种情况。我将不胜感激任何其他模式或解决方案。还要澄清只有一个线程。

提前致谢。

您需要的是某种同步状态传播的信号量。当 subject 传播状态变化时,它首先设置一个信号量,该信号量将锁定 subject 的任何进一步状态变化(或简单的状态变化传播)。这也可以通过 subject 的观察者模式中的堆栈来实现。只有在所有客户端都被告知状态更改后,信号量才会被释放。通过这种方式,状态更改的发送可以保证按照在 subject.

上执行的顺序到达所有客户端

如果您使用状态机对上述内容建模,您将使用历史状态机。

经过数小时的思考,我想我发现 solution.It 可能与 Thoms Kilian 的建议有关。关键是某种 post 方法,它将那些改变主题状态的方法排队。一种可能的实现是使用处理程序和 post 那些方法到主线程(记住没有更多的线程):

client -> subject.anyMethod() //changes subject state to state X
subject -> handler.post(anyMethod())
//nothing to do, so post is executed
subject -> notifyObservers(X) // subject FIRST notification waterfall
observerA -> subject.anyMethod() //changes subject to state Y
//here comes the change
subject -> handler.post(anyMethod())
//pc keeps sending rest of notifications before executing the posted runnable and the second waterfall

这样所有观察者在更改时都可以访问相同的状态并对未来的事件进行排队:)