我们使用状态机'框架'(基于状态模式),它不暴露其当前状态,这有时意味着我必须以迂回的方式做事。
当我质疑这个设计决定时,其中一个理由是“如果你需要知道当前的状态,你就错了”。
这是对的吗?我不是国家机器方面的专家。
(我在这里问,因为我知道我有一个固有的偏见反对状态模式,我发现它太冗长了。)
示例
想象一个系统,其中一个状态读取两个传感器。一个传感器给出一个数值,另一个给出一个布尔值,它告诉你第一个是否“可靠”。系统根据最后的 n 良好值输出一个当前“良好”值或插值(或其他一些花哨计算)的值。
我的想法是有两个子状态 - 一个'好',另一个'不'。当一个新值到来时,我想询问状态机状态,以便我知道如何处理插值。
(我想我已经回答了我自己的问题:解决方案是在状态机中有一个NewDataValue(val)
事件,它只会将值从'良好'状态转发出去?)
答案 0 :(得分:10)
我必须同意那个“使用错误”评论的人。
状态机的重点是成为一个黑盒子,事件被抽入其中,并根据这些事件(包括状态转换)导致某些事情发生。事件本身不应完全依赖于机器的当前状态。
我无法想象事件应该根据当前状态而改变的一种情况(但如果你有的话,请随时启发我)。
事件将始终成为现实。如果需要根据当前状态以不同方式处理,那么状态机本身就会出现问题,而不是事件泵。
事实上,基于当前状态更改事件的整个想法在封装面前飞逝。
最好的状态机有一个非常简单的形式:
+------+
| | state
V | transitions
+---------------+ |
events --> | | --+
| state machine |
effects <-- | |
+---------------+
换句话说,事件以某种方式被泵入其中(独立于状态),并且基于其状态和事件具有某些效果。它保持着自己的状态。
就你的问题的更新而言,你希望根据最后一次读数是好还是基于以前的读数来处理输出,我只想把它放在效果部分。让状态机输出当前值 plus ,指示它是来自传感器还是计算出来。
然后,处理效果的代码可以使用该信息执行所需的操作。这有效地为您提供了所需的信息,并没有打破黑盒的性质。
答案 1 :(得分:2)
嗯,这是真正的问题。为什么需要知道状态机的当前状态?你打算用它做什么?
如果您是第二次猜测它,那就是根据当前状态和新输入尝试预测状态机将来的位置,那么您将运行与状态机并行运行的东西。不管是好还是坏,取决于你做什么以及为什么这样做。
表面上看,状态机是一个黑盒子(或者在某些情况下,它看起来像一台老虎机!),你将数据输入并从中提取数据。
就像编程中的任何东西一样,没有必要把东西变成不透明的黑盒子。事情总是可以是带有输入槽和输出槽的透明盒装盒,但你至少可以看到它们内部运行的齿轮。但是如果你试图解决这个问题,它就会与抽象相反,因为状态机被设计为封装一个逻辑块。
因此,结构的不透明性并不是真正的问题,而是您在尝试获取信息时尝试处理的信息。
答案 2 :(得分:2)
“如果您需要知道当前状态,那么您使用它是错误的”。 - 那是对的。
目前的状态无法曝光。所有需要你采取不同行为的事情,因为处于特定状态,应放在该状态的内部(且仅在那里) - 作为从公共方式调用的私有方法,或作为公共方式,在其他州没有任何东西(或其他东西)。你的“状态机”必须工作......你从外面看,不应该知道原因。
答案 3 :(得分:0)
在分层系统设计中,通常较高级别的对象仅知道较低级别对象的状态的抽象,例如state_good抽象(完美,可接受,......)和state_bad抽象(failed1,failed2,failed3 ..)。
在非分层系统中,一个对象可以准确地知道另一个对象的状态,特别是如果对象被分配了不同的任务。
-Janusz