175
技術社區[雲棲]
哥特式建築安全係統
本文講的是哥特式建築安全係統,在我的童年記憶裏,電視上播放的那些低劣的冒險電影是模煳卻持久的。通常,這些電影的場景會安排某個古舊的城堡、密室或走廊在其中起著重要的作用。為了找到它們,英雄們需要拉動樓頂的蠟燭托架,然後,輕拍兩次牆壁。
想象有這樣一家公司,他們決定根據這個想法構建一套安全係統。他們進入之後,設置某種無線網絡,安裝一些小的設備。如果發生某些有趣的事情,這些設備會發出一條四字符的消息。比如,打開抽屜,抽屜上附著的感應器就會發出一條消息:D2OP。還有一些小的控製設備,響應這樣的四字符命令消息,比如,某個設備收到D1UL消息,就會打 開一扇門。
所有這一切的核心是一些控製器軟件,它們會監聽事件消息,弄清楚要做什麼,然後發送命令消息。在那個網絡產業崩潰的年代,這家公司買到了一堆廉價的烤麵包機,它們可以用Java控製,所以,公司準備用它們來做控製器。因此,隻要客戶買了哥特式建築安全係統,公司就會進駐其中,給這個建築物裝上一大堆設備,當然,還有一個烤麵包機,裏麵裝有Java編寫的控製程序。
就這個例子而言,我們的關注點在於這個控製程序。每個客戶都有各自的需求,但是,隻要有一些好的樣本,我們就不難發現其中的通用模式。為了打開密室,格蘭特小姐要關上臥室房門,打開抽屜,然後,再開一盞燈。而肖瓦小姐則先要打開水龍頭,再打開正確的燈,從而開啟兩個密室中的一個。至於史密斯小姐,她的辦公室裏有一個上鎖的壁櫥,內有一個密室。她必須先關上門,把牆上的畫摘下來,再打開桌子上的燈三次,最後,打開那個滿滿的櫥櫃最上麵的抽屜,這時,壁櫥打開了。如果在打開裏麵的密室前,她忘記了關閉桌子上的燈,就會警報大作。
這是個異想天開的例子,但它所要表達的意圖一點都不特別。我們有這樣一係列係統,它們共享著大多數組件和行為,卻彼此間差異極大。在這個例子裏,對所有的客戶來說,控製器發送和接收消息的方式是相同的,但是產生的事件序列和發送的命令卻不盡相同。我們要整理一下這些東西,這樣,當公司安裝一個全新係統時,付出的代價才會是最小的。因此,對他們而言,為控製器編寫動作序列必須非常簡單才行。
了解了所有這些情況,一種好的處理方式浮出水麵:把控製器看做狀態機(state machine)。每個感應器都可以發送事件(event),改變控製器的狀態(state)。當控製器進入某種狀態時,它就會在網絡上發出一條命令消息。
至此,我應該坦白,寫作之初,這是全然不同的。狀態機是一個很好的DSL例子,因此,我先選擇了它。之所以選擇 哥特式城堡,是因為我厭倦了其他所有狀態機的例子。
格蘭特小姐的控製器
這家神秘的公司擁有成千上萬感到滿意的客戶,但在這裏,我們隻準備強調其中的一位:格蘭特小姐,我最喜歡的客戶。她的臥室裏有個密室,通常情況下,這個密室都會緊鎖著,隱蔽在那裏。要打開這個密室,她就要關上門,然後,打開櫃子裏的第二個抽屜,打開床邊的燈─二者順序任意。做完這些,秘密麵板就會解鎖,她就可以打開密室了。
我用一張狀態圖來表示這個序列(見圖1-1)。
如果你沒接觸過狀態機,其實,它們隻不過是描述行為的一種常見方式而已─並非廣泛適用,但對於類似這樣的情況,卻是再合適不過了。其基本的想法是,控製器會處於不同的狀態。當它們處於某個特定的狀態時,某個事件會讓控製器轉換為另一個狀態,在那種狀態下會有不同的轉換(transition)。因此,一係列的事件會讓控製器從一個狀態進到另一個狀態。在這個模型裏,當進入一個狀態時,會執行某個動作(比如發送消息)。(其他類型的狀態機可能會在不同的地方執行動作)。
基本上,這個控製器就是一個簡單的傳統狀態機,不過需要一些微調。客戶的控製器要有一個明確的空閑(idle) 態,係統會有大多數的時間處在該狀態。某種特定的事件就可以讓係統跳回到這個空閑態,即便它正處於一個更有趣的狀態轉換中間,這樣就可以有效地重置整個模型了。在格蘭特小姐的這個例子裏,開門就是這樣一個重置事件。
引入重置事件,意味著這裏描述的狀態機並不完全滿足某種經典的狀態機模型。狀態機有幾種非常有名的變體,這個模型便是以其中一個為起點的,隻是略做微調,增加了重置事件,也就變成了隻針對這種情況。
需要特別注意的是,嚴格來說,未必一定要有重置事件才能表示格蘭特小姐的控製器。一種替代方案是,為每個狀態添加一個轉換,隻要觸發doorOpened,就會轉換為空閑態。重置事件這個想法很有用,因為它簡化了整個狀態圖。
來源:華章計算機
原文標題:哥特式建築安全係統
最後更新:2017-09-20 17:03:29