2011-03-23 109 views
8

我們使用了一個狀態機框架(基於狀態模式),它不暴露它的當前狀態,這有時意味着我必須以迂迴的方式來做事情。狀態機是否需要公開其當前狀態?

當我質疑這個設計決定時,其中一個理由是「如果您需要知道當前狀態,那麼您錯誤地使用了它」。

這是正確的嗎?我並不是國家機器專家。

(我問這裏是因爲我知道我有一個固有的偏見狀態模式,我覺得這太冗長。)

想象一下,一個系統中的一個它表示讀取兩個傳感器。一個傳感器給出一個數值,另一個傳感器給出一個布爾值,告訴你第一個是否'可靠'。系統根據最近的良好值輸出一個值,該值可以是當前的「良好」值,也可以是插值(或其他奇特計算)。

我的想法是有兩個子狀態 - 一個「好」,另一個「不」。當一個新的值到達時,我想問狀態機是哪個狀態,以便我知道如何處理插值。

(我想我已經回答了我的問題:該解決方案是在狀態機NewDataValue(val)事件,這將只轉發從「好」的狀態值?)

回答

10

我不得不同意做出「使用錯誤」評論的人。

狀態機的全部要點是一個黑盒子,事件被抽入其中並根據這些事件(包括狀態轉換)導致某些事情發生。事件本身不應該依賴於機器的當前狀態。

我不能設想一個情況,其中事件應該根據當前狀態而改變(但如果有的話,隨時給我啓發)。

事件將總是是什麼。如果需要根據當前狀態對進行處理,則這是狀態機本身的問題,而不是事件泵。

實際上,基於當前狀態改變事件的整個想法都是在封裝的情況下進行的。

最好的狀態機有一個非常簡單的形式:

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

換句話說,事件被泵入它以某種方式(獨立國家),它具有基於其狀態和事件有一定的影響。它保持着自己的狀態。


在更新你的問題,你想以不同的處理基於上次讀數是好還是基於以前的公式輸出方面,我只想提出,在效果部分。讓狀態機輸出當前值加上表示它是來自傳感器還是計算出的。

然後你的代碼處理效果可以做它喜歡的信息。這有效地爲您提供了所需的信息,並且不會破壞黑盒子的本質。

+0

+1我得說我開悟了! – Nilesh 2011-03-23 07:12:14

+0

我有一個例子(見我更新的問題),但我想我已經自己回答了:) – Benjol 2011-03-23 08:39:48

2

嗯,這是真正的問題。爲什麼你需要知道狀態機的當前狀態?你打算用它做什麼?

如果你第二次猜測它,那就是試圖根據當前狀態和新輸入來預測未來狀態機的位置,然後你就可以並行運行一些狀態機。不知道這是好還是壞,取決於你在做什麼,爲什麼。

表面上,狀態機是一個黑盒子(或者在某些情況下,它看起來像一臺老虎機!),您將數據提供給數據並將數據提取出來。

和編程中的任何東西一樣,沒有必要把事物變成不透明的黑盒子。東西總是可以是帶有輸入插槽和輸出插槽的機箱,但至少可以看到它們內部的齒輪。但是,如果你試圖解決這個問題,它就與抽象相反,因爲狀態機被設計爲封裝一個邏輯塊。

因此,結構的不透明性並不是真正的問題,這是您在獲取信息時想要處理的信息。

+3

恐怕我不得不不同意「不需要事物是不透明的黑盒子」。這總是會導致信息泄漏,並且人們依賴這些信息。當你試圖讓你的代碼更高效時,這些人會跟蹤你並擊敗你,從而打破他們依賴的漏洞。除非您希望永久鎖定它,否則您不會在數據結構外提供信息。 – paxdiablo 2011-03-23 06:56:14

+0

僅僅因爲這個過程是開放的,並不意味着它必須被破壞。你的合同是明確的,這個實施可能很好地提供了合同上的燈光,但它並沒有使合同變得不合法。如果其他人試圖違反該合同,那就是他們的問題。您可能希望在黑暗,鎖定,充滿煙霧的房間中開展業務。我更喜歡我的陽光。我更喜歡露天燒烤,所以我可以看到正在製作的食物。我更願意相信我的用戶,而不是因爲他們可能做什麼而鎖定他們。我想你選擇不相信你的。 – 2011-03-23 16:24:08

2

「如果您需要知道當前狀態,則表明您使用的是錯誤的」。 - 這是正確的。

當前狀態無法顯示。所有那些因爲處於特定狀態而需要採取不同行動的事物應該被置於該狀態的內部(並且僅在那裏) - 作爲從公共方面調用的私人方法,或者作爲公共,無所事事(或其他)在其他國家。你的「狀態機」必須工作......而你從外面看,不應該知道爲什麼。

0

在分級系統設計中,通常較高級別的對象只知道較低級別對象狀態的抽象,例如, state_good抽象(完美,可接受,...)和state_bad抽象(failed1,failed2,failed3 ..)。

在非分層系統中,一個對象精確地知道另一個對象的狀態是可以的,特別是如果對象被分配了不相似的任務。

-Janusz