天天看點

《領域特定語言》一第1章 入 門 例 子1.1 哥特式建築安全系統

落筆之初,我需要快速地解釋一下本書的内容,就是解釋什麼是領域特定語言(domain– specific language,dsl)。為達此目的,我一般都會先展示一個具體的例子,随後再給出抽象的定義。是以,我會從一個例子開始,展示dsl可以采用的不同形式。在第2章裡,我會試着把這個定義概括為一些更廣泛适用的東西。

在我的童年記憶裡,電視上播放的那些低劣的冒險電影是模糊卻持久的。通常,這些電影的場景會安排某個古舊的城堡、密室或走廊在其中起着重要的作用。為了找到它們,英雄們需要拉動樓頂的蠟燭托架,然後,輕拍兩次牆壁。

想象有這樣一家公司,他們決定根據這個想法建構一套安全系統。他們進入之後,設定某種無線網絡,安裝一些小的裝置。如果發生某些有趣的事情,這些裝置會發出一條四字元的消息。比如,打開抽屜,抽屜上附着的感應器就會發出一條消息:d2op。還有一些小的控制裝置,響應這樣的四字元指令消息,比如,某個裝置收到d1ul消息,就會打 開一扇門。

所有這一切的核心是一些控制器軟體,它們會監聽事件消息,弄清楚要做什麼,然後發送指令消息。在那個網絡産業崩潰的年代,這家公司買到了一堆廉價的烤面包機,它們可以用java控制,是以,公司準備用它們來做控制器。是以,隻要客戶買了哥特式建築安全系統,公司就會進駐其中,給這個建築物裝上一大堆裝置,當然,還有一個烤面包機,裡面裝有java編寫的控制程式。

就這個例子而言,我們的關注點在于這個控制程式。每個客戶都有各自的需求,但是,隻要有一些好的樣本,我們就不難發現其中的通用模式。為了打開密室,格蘭特小姐要關上卧室房門,打開抽屜,然後,再開一盞燈。而肖瓦小姐則先要打開水龍頭,再打開正确的燈,進而開啟兩個密室中的一個。至于史密斯小姐,她的辦公室裡有一個上鎖的壁櫥,内有一個密室。她必須先關上門,把牆上的畫摘下來,再打開桌子上的燈三次,最後,打開那個滿滿的櫥櫃最上面的抽屜,這時,壁櫥打開了。如果在打開裡面的密室前,她忘記了關閉桌子上的燈,就會警報大作。

這是個異想天開的例子,但它所要表達的意圖一點都不特别。我們有這樣一系列系統,它們共享着大多數元件和行為,卻彼此間差異極大。在這個例子裡,對所有的客戶來說,控制器發送和接收消息的方式是相同的,但是産生的事件序列和發送的指令卻不盡相同。我們要整理一下這些東西,這樣,當公司安裝一個全新系統時,付出的代價才會是最小的。是以,對他們而言,為控制器編寫動作序列必須非常簡單才行。

了解了所有這些情況,一種好的處理方式浮出水面:把控制器看做狀态機(state machine)。每個感應器都可以發送事件(event),改變控制器的狀态(state)。當控制器進入某種狀态時,它就會在網絡上發出一條指令消息。

至此,我應該坦白,寫作之初,這是全然不同的。狀态機是一個很好的dsl例子,是以,我先選擇了它。之是以選擇 哥特式城堡,是因為我厭倦了其他所有狀态機的例子。

格蘭特小姐的控制器

這家神秘的公司擁有成千上萬感到滿意的客戶,但在這裡,我們隻準備強調其中的一位:格蘭特小姐,我最喜歡的客戶。她的卧室裡有個密室,通常情況下,這個密室都會緊鎖着,隐蔽在那裡。要打開這個密室,她就要關上門,然後,打開櫃子裡的第二個抽屜,打開床邊的燈─二者順序任意。做完這些,秘密面闆就會解鎖,她就可以打開密室了。

我用一張狀态圖來表示這個序列(見圖1-1)。

《領域特定語言》一第1章 入 門 例 子1.1 哥特式建築安全系統

如果你沒接觸過狀态機,其實,它們隻不過是描述行為的一種常見方式而已─并非廣泛适用,但對于類似這樣的情況,卻是再合适不過了。其基本的想法是,控制器會處于不同的狀态。當它們處于某個特定的狀态時,某個事件會讓控制器轉換為另一個狀态,在那種狀态下會有不同的轉換(transition)。是以,一系列的事件會讓控制器從一個狀态進到另一個狀态。在這個模型裡,當進入一個狀态時,會執行某個動作(比如發送消息)。(其他類型的狀态機可能會在不同的地方執行動作)。

基本上,這個控制器就是一個簡單的傳統狀态機,不過需要一些微調。客戶的控制器要有一個明确的空閑(idle) 态,系統會有大多數的時間處在該狀态。某種特定的事件就可以讓系統跳回到這個空閑态,即便它正處于一個更有趣的狀态轉換中間,這樣就可以有效地重置整個模型了。在格蘭特小姐的這個例子裡,開門就是這樣一個重置事件。

引入重置事件,意味着這裡描述的狀态機并不完全滿足某種經典的狀态機模型。狀态機有幾種非常有名的變體,這個模型便是以其中一個為起點的,隻是略做微調,增加了重置事件,也就變成了隻針對這種情況。

需要特别注意的是,嚴格來說,未必一定要有重置事件才能表示格蘭特小姐的控制器。一種替代方案是,為每個狀态添加一個轉換,隻要觸發dooropened,就會轉換為空閑态。重置事件這個想法很有用,因為它簡化了整個狀态圖。

下一篇: 堆棧

繼續閱讀