1. 程式人生 > >【軟件構造】第六章第三節 面向可維護的構造技術

【軟件構造】第六章第三節 面向可維護的構造技術

pre 協議 判斷 regex 格式 png ria 不包含 有一個

第六章第三節 面向可維護的構造技術

學了這麽多OO設計模式,不外乎都是 delegation + subtying,萬變不離其宗。

除了OO,還有什麽其他能夠提升軟件可維護性的構造技術?——本節從委派+子類型跳出來,學習以下三個方面:
(1) 基於狀態的構造技術 (2) 表驅動的構造技術 (3) 基於語法的構造技術

Outline

  • 基於狀態的構造技術
    • 狀態模式(State Pattern)
    • 備忘錄模式(Memento Pattern)
  • 基於語法的構造技術
  • 正則語法與正則表達式

Notes

## 基於狀態的構造技術

【狀態模式(State Pattern)】

【備忘錄模式(Memento Pattern)】

## 基於語法的構造技術

【運用場景】

  • 有一類應用,從外部讀取文本數據, 在應用中做進一步處理。 具體來說,讀取的一個字節或字符序列可能是:
  • 輸入文件有特定格式,程序需讀取文件並從中抽取正確的內容。
  • 從網絡上傳輸過來的消息,遵循特定的協議。
  • 用戶在命令行輸入的指令,遵頊特定的格式。
  • 內存中存儲的字符串,也有格式需要。

對於這些類型的序列,語法的概念是設計的一個好選擇:

  • 使用grammar判斷字符串是否合法,並解析成程序裏使用的數據結構 。
  • 正則表達式
  • 通常是遞歸的數據結構 。

【語法成分】

terminals 終止節點、葉節點

nonterminal 非終止節點(遵循特定規則,利用操作符、終止節點和其他非終止節點,構造新的字符串)

【語法中的操作符】

  • 三個基本語法的操作符:
    • 連接,不是通過一個符號,而是一個空間:
      • x ::= y z //x等價於y後跟一個z
    • 重復,以*表示:  
      • x ::= y* // x等價於0個或更多個y
    • 聯合,也稱為交替,如圖所示 | :  
      • x ::= y | z //x等價於一個y或者一個z
  • 三個基本操作符的組合:
    • 可選(0或1次出現),由?表示:
      • x ::= y? //x等價於一個y或者一個空串
    • 出現1次或多次:以+表示:
      • x ::= y+ //x等價於一個或者更多個y, 等價於 x ::= y y*
    • 字符類[…],表示長度的字符類,包含方括號中列出的任何字符的1個字符串:
      • x ::= [abc] //等價於 x ::= ‘a‘ | ‘b‘ | ‘c‘
    • 否定的字符類[^…],表示長度,包含未在括號中列出的任何字符的1個字符串:
      • x ::= [^abc] //等價於 x ::= ‘d‘ | ‘e‘ | ‘f‘ | ... (all other characters in Unicode)
  • 例子:
    • x ::= (y z | a b)* //an x is zero or more y z or a b pairs
    • m ::= a (b|c) d //an m is a, followed by either b or c, followed by d

【實例:使用語法構造URL】

  • 寫一個語法表達式,表達如下的若幹URL(域名)
    • http://google.com/
    • http://baidu.com/
    • http://stanford.edu/
  • 我們可以用如下的一行表達式表示
    url ::= ‘http://‘ [a-z]+ ‘.‘ [a-z]+  ‘/‘ 
  • 用語法樹可表示為如下形式:

技術分享圖片

hostname可以有兩個以上的部分,並且可以有一個可選的端口號:http://didit.csail.mit.edu:4949/
為了處理這樣的字符串,語法可以這樣寫:

技術分享圖片

【Markdown 和 HTML的語法】

技術分享圖片

技術分享圖片

## 正則語法與正則表達式

  • 正則語法:簡化之後可以表達為一個產生式而不包含任何非終止節點。
  • 正則語法示例:
//Rugular!
url ::= ‘http://‘ ([a-z]+ ‘.‘)+ [a-z]+ (‘:‘ [0-9]+)? ‘/‘

//Regular!
markdown ::= ([^_]* | ‘_‘ [^_]* ‘_‘ )* 

//Not Regular!
html ::= ( [^<>]* | ‘<i>‘ html ‘<i>‘ )*

  • 正則表達式(regex):去除引號和空格,從而表達更簡潔(更難懂)技術分享圖片
  • 在Java中使用正則表達式
    • 適用場合:我們用正則表達式匹配字符串(例如 String.split , String.matches , java.util.regex.Pattern
    • 用一個空格代替所有的多個空格 技術分享圖片
    • 匹配一個URL:技術分享圖片
    • 提取HTML標簽的一部分技術分享圖片

附:正則語法

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

【解釋器模式( Interpreter Pattern)】

【軟件構造】第六章第三節 面向可維護的構造技術