Pattern: 解譯器模式
Class Diagram: 摩斯電碼
情境:讓我們試著作一個摩斯電碼機,它會將一般句子轉成摩斯電碼的表示
- 首先是語境類別 (Context)
1 |
|
主要是承載要解譯的詞句,
會隨著解譯進度,改變其內容。
- 接著是表達式類別 (Expression)
1 |
|
這邊說明一下,所謂的摩斯電碼,
是利用滴答兩種不同長短訊號的排列組合,
來表達每一個字母符號。
例如:A的表示為 (.-)。
而在此處的範例中,
同個單字的字母會用空格 ( ) 分開,
不同單字的字母則會用斜槓 (/) 分開。
例如:Good Morning的表示會是 (–. — — -.. / – — .-. -. .. -. –.)。
字母間不區分大小寫。
按照上述規則,我想區分出兩種表達式 (Expression)。
解譯字母符號的為終端表達式 (Terminal Expression) ,
其他情況為非終端表達式 (NonTerminal Expression) 。
想法是使用非終端表達式時,表示還有字需要解譯。
- 實作非終端表達式 (NonTerminal Expression)
1 |
|
此處interpret()方法會將目前解譯到的詞句,去除前後空白。
execute()方法則會印出斜槓 (/)。
而isSpace()方法,會在待會的客戶端程式碼用到。
- 實作終端表達式 (Terminal Expression)
1 |
|
此處interpret()方法會找出要解譯的單字,並截斷它。
execute()方法則會逐步印出單字中的每一個字母符號,彼此間以空格隔開。
- 實作客戶端的程式碼
1 |
|
最後讓我們來看客戶端程式碼怎麼跑吧!
以Hello World為例:
- 首先會將Hello World轉成語境類別 (Context) 。
- 終端表達式 (Terminal Expression) 會截取出Hello這個單字,印出它的摩斯電碼。
- 非終端表達式 (NonTerminal Expression) 則會去除空白,印出斜槓 (/)。
- 終端表達式 (Terminal Expression) 會截取出World這個單字,印出它的摩斯電碼。
- 客戶端程式碼判斷解譯完成,結束迴圈。
[單一職責原則]
語境類別 (Context) :負責乘載要解譯的詞句。
非終端表達式 (NonTerminal Expression) :負責連結解譯單字間的文法。
終端表達式 (Terminal Expression) :負責解譯每一個字母符號。
[開放封閉原則]
增加要轉譯的字母符號時,僅需修改終端表達式 (Terminal Expression)。
[依賴反轉原則]
透過表達式 (Expression) 接口,
確保各個表達式都有interpret()方法與execute()方法。
現實中幾乎沒有機會使用到的設計模式,
範例想了很多天,希望這樣有傳達出這個模式的精神!
另外這個範例還沒有完成decode()方法,
也就是從摩斯電碼轉回一般句子。
之後有時間會試著實作看看。
ʕ •ᴥ•ʔ:目前心目中前三難的設計模式。