状态机是否需要暴露其当前状态?

时间:2011-03-23 06:13:05

标签: design-patterns state-machine

我们使用状态机'框架'(基于状态模式),它不暴露其当前状态,这有时意味着我必须以迂回的方式做事。

当我质疑这个设计决定时,其中一个理由是“如果你需要知道当前的状态,你就错了”。

这是对的吗?我不是国家机器方面的专家。

(我在这里问,因为我知道我有一个固有的偏见反对状态模式,我发现它太冗长了。)

示例

想象一个系统,其中一个状态读取两个传感器。一个传感器给出一个数值,另一个给出一个布尔值,它告诉你第一个是否“可靠”。系统根据最后的 n 良好值输出一个当前“良好”值或插值(或其他一些花哨计算)的值。

我的想法是有两个子状态 - 一个'好',另一个'不'。当一个新值到来时,我想询问状态机状态,以便我知道如何处理插值。

(我想我已经回答了我自己的问题:解决方案是在状态机中有一个NewDataValue(val)事件,它只会将值从'良好'状态转发出去?)

4 个答案:

答案 0 :(得分:10)

我必须同意那个“使用错误”评论的人。

状态机的重点是成为一个黑盒子,事件被抽入其中,并根据这些事件(包括状态转换)导致某些事情发生。事件本身不应完全依赖于机器的当前状态。

我无法想象事件应该根据当前状态而改变的一种情况(但如果你有的话,请随时启发我)。

事件将始终成为现实。如果需要根据当前状态以不同方式处理,那么状态机本身就会出现问题,而不是事件泵。

事实上,基于当前状态更改事件的整个想法在封装面前飞逝。

最好的状态机有一个非常简单的形式:

                         +------+
                         |      | state
                         V      |  transitions
            +---------------+   |
 events --> |               | --+
            | state machine |
effects <-- |               |
            +---------------+

换句话说,事件以某种方式被泵入其中(独立于状态),并且基于其状态和事件具有某些效果。它保持着自己的状态。


就你的问题的更新而言,你希望根据最后一次读数是好还是基于以前的读数来处理输出,我只想把它放在效果部分。让状态机输出当前值 plus ,指示它是来自传感器还是计算出来。

然后,处理效果的代码可以使用该信息执行所需的操作。这有效地为您提供了所需的信息,并没有打破黑盒的性质。

答案 1 :(得分:2)

嗯,这是真正的问题。为什么需要知道状态机的当前状态?你打算用它做什么?

如果您是第二次猜测它,那就是根据当前状态和新输入尝试预测状态机将来的位置,那么您将运行与状态机并行运行的东西。不管是好还是坏,取决于你做什么以及为什么这样做。

表面上看,状态机是一个黑盒子(或者在某些情况下,它看起来像一台老虎机!),你将数据输入并从中提取数据。

就像编程中的任何东西一样,没有必要把东西变成不透明的黑盒子。事情总是可以是带有输入槽和输出槽的透明盒装盒,但你至少可以看到它们内部运行的齿轮。但是如果你试图解决这个问题,它就会与抽象相反,因为状态机被设计为封装一个逻辑块。

因此,结构的不透明性并不是真正的问题,而是您在尝试获取信息时尝试处理的信息。

答案 2 :(得分:2)

“如果您需要知道当前状态,那么您使用它是错误的”。 - 那是对的。

目前的状态无法曝光。所有需要你采取不同行为的事情,因为处于特定状态,应放在该状态的内部(且仅在那里) - 作为从公共方式调用的私有方法,或作为公共方式,在其他州没有任何东西(或其他东西)。你的“状态机”必须工作......你从外面看,不应该知道原因。

答案 3 :(得分:0)

在分层系统设计中,通常较高级别的对象仅知道较低级别对象的状态的抽象,例如state_good抽象(完美,可接受,......)和state_bad抽象(failed1,failed2,failed3 ..)。

在非分层系统中,一个对象可以准确地知道另一个对象的状态,特别是如果对象被分配了不同的任务。

-Janusz