在Android应用程序的开发过程中,我遇到了这个设计难题,我目前无法解决。我会很感激任何想法,解决方法或干净的解决方案:)我会尝试尽可能地简化它:
一切都以一个共同的观察者模式实现开始。有一个主题在其公共方法调用中改变了状态;并且有观察员对这些变化做出相应的反应。 在这种情况下,主题是一个STATEFUL主题,这意味着它有一个内部状态控制器(一个int),它像自动机一样变化。每次状态改变时,它都会像往常一样通知观察者:
但现在想想这种情况:
由于SECOND瀑布,现在将要发生的事情是,下一个观察者(让观察者B说)将收到通知作为状态Y(来自最后的第二个瀑布),相应地采取行动,当这个SECOND瀑布完成时,PC(程序计数器)将继续FIRST通知瀑布并重新通知观察者B OLD STATE X.这会产生两个主要问题:第一个观察者B以错误的顺序得到新状态的通知(第一个)状态Y,然后状态X,当它应该是相反的方式)和第二个也是最重要的,甚至以错误的顺序通知,当观察者B接收到新状态X的通知时,它完全是错误的,因为主体真实状态是Y;这会产生很多问题。
正如您可能已经意识到的那样,当观察者提交主体状态的变化时,当它被通知而不是仅从主体获取gettind数据时,就会发生这种情况。我将不胜感激任何其他模式或解决方案。另外澄清只有一个主题。
提前致谢。
答案 0 :(得分:2)
您需要的是某种同步状态传播的信号量。当subject
传播状态更改时,它首先设置一个信号量,该信号量将锁定subject
的任何进一步的状态更改(或简单地传播状态更改)。这也可以通过subject
的观察者模式内的堆栈来实现。只有在所有客户端都被告知状态更改后,信号量才会被释放。这样,发送状态更改可以保证按照subject
上执行的顺序到达所有客户端。
如果使用状态机对上述内容进行建模,则可以使用历史状态机。
答案 1 :(得分:2)
经过几个小时的琢磨,我想我找到了一个可能的解决方案。这与Thoms Kilian提出的建议有关。关键是某种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
这样,所有观察者在更改时都会访问相同的状态并对未来事件进行排队:)