在實際項目開發中如果需要解析數學公式,無須再運用解譯器模式進行設計,可以直接使用一些第三方解析工具包,它們可以統稱為數學運算式解析器(Math Expression Parser, MEP),如Expression4J、Jep、JbcParser、Symja、Math Expression String Parser(MESP)等來取代解譯器模式,它們可以方便地解釋一些較為複雜的文法,功能強大,且使用簡單,效率較好。
觀察者模式是設計模式中的“超級模式”,其應用隨處可見,在之後幾篇文章裡,我將向大家詳細介紹觀察者模式。 “紅燈停,綠燈行”,在日常生活中,交通號誌裝點著我們的城市,指揮著日益擁擠的城市交通。當紅燈亮起,來往的汽車將停止;而綠燈亮起,汽車可以繼續前行。在這個過程中,交通號誌是汽車(更準確地說應該是汽車駕駛員)的觀察目標,而汽車是觀察者。隨著交通號誌的變化,汽車的行為也將隨之而變化,一盞交通號誌可以指揮多輛汽車。22-1所示:圖22-1
由於外觀類維持了對多個子系統類的引用,外觀對象在系統運行時將佔用較多的系統資源,因此需要對外觀對象的數量進行限制,避免系統資源的浪費。可以結合單例模式對外觀類進行改進,將外觀類設計為一個單例類。通過對面板模式單例化,可以確保系統中只有唯一一個訪問子系統的入口,降低系統資源的消耗。單例化之後的面板模式結構6所示:圖6 單例外觀類結構圖
22.2 觀察者模式概述 觀察者模式是使用頻率最高的設計模式之一,它用於建立一種對象與對象之間的依賴關係,一個對象發生改變時將自動通知其他對象,其他對象將相應作出反應。在觀察者模式中,發生改變的對象稱為觀察目標,而被通知的對象稱為觀察者,一個觀察目標可以對應多個觀察者,而且這些觀察者之間可以沒有任何相互聯絡,可以根據需要增加和刪除觀察者,使得系統更易於擴充。 觀察者模式定義如下:觀察者模式(Observer
23.3 完整解決方案 為了實現對象之間的聯動,Sunny軟體公司開發人員決定使用觀察者模式來進行多人聯機對戰遊戲的設計,其基本結構22-4所示:圖22-4 多人聯機對戰遊戲結構圖 在圖22-4中,AllyControlCenter充當目標類,ConcreteAllyControlCenter充當具體目標類,Observer充當抽象觀察者,Player充當具體觀察者。完整代碼如下所示:import java.util.*;//抽象觀察類interface Observer
18.2 文法規則和抽象文法樹 解譯器模式描述了如何為簡單的語言定義一個文法,如何在該語言中表示一個句子,以及如何解釋這些句子。在正式分析解譯器模式結構之前,我們先來學習如何表示一個語言的文法規則以及如何構造一棵抽象文法樹。 在前面所提到的加法/減法解譯器中,每一個輸入運算式,例如“1 + 2 + 3 – 4 + 1”,都包含了三個語言單位,可以使用如下文法規則來定義:expression ::= value | operationoperation ::=
俗話說:條條大路通羅馬。在很多情況下,實現某個目標的途徑不止一條,例如我們在外出旅遊時可以選擇多種不同的出行方式,如騎單車、坐汽車、坐火車或者坐飛機,可根據實際情況(目的地、旅遊預算、旅遊時間等)來選擇一種最適合的出行方式。在制訂旅行計劃時,如果目的地較遠、時間不多,但不差錢,可以選擇坐飛機去旅遊;如果目的地雖遠、但假期長、且需控制旅遊成本時可以選擇坐火車或汽車;如果從健康和環保的角度考慮,而且有足夠的毅力,單車遊或者徒步旅遊也是個不錯的選擇,。
22.4 JDK對觀察者模式的支援 觀察者模式在Java語言中的地位非常重要。在JDK的java.util包中,提供了Observable類以及Observer介面,它們構成了JDK對觀察者模式的支援。22-5所示:圖22-5 JDK提供的Observable類及Observer介面結構圖 (1) Observer介面 在java.util.Observer介面中只聲明一個方法,它充當抽象觀察者,其方法聲明代碼如下所示:void
18.3 解譯器模式概述 解譯器模式是一種使用頻率相對較低但學習難度較大的設計模式,它用於描述如何使用物件導向語言構成一個簡單的語言解譯器。在某些情況下,為了更好地描述某一些特定類型的問題,我們可以建立一種新的語言,這種語言擁有自己的運算式和結構,即文法規則,這些問題的執行個體將對應為該語言中的句子。此時,可以使用解譯器模式來設計這種新的語言。對解譯器模式的學習能夠加深我們對物件導向思想的理解,並且掌握程式設計語言中文法規則的解釋過程。
24.2 策略模式概述 在策略模式中,我們可以定義一些獨立的類來封裝不同的演算法,每一個類封裝一種具體的演算法,在這裡,每一個封裝演算法的類我們都可以稱之為一種策略(Strategy),為了保證這些策略在使用時具有一致性,一般會提供一個抽象的策略類來做規則的定義,而每種演算法則對應於一個具體策略類。
22.5 觀察者模式與Java事件處理 JDK 1.0及更早版本的事件模型基於職責鏈模式,但是這種模型不適用於複雜的系統,因此在JDK 1.1及以後的各個版本中,事件處理模型採用基於觀察者模式的委派事件模型(DelegationEvent Model, DEM),即一個Java組件所引發的事件並不由引發事件的對象自己來負責處理,而是委派給獨立的事件處理對象負責。
18.4 完整解決方案 為了能夠解釋機器人控制指令,Sunny軟體公司開發人員使用解譯器模式來設計和實現機器人控製程序。針對五條文法規則,分別提供五個類來實現,其中終結符運算式direction、action和distance對應DirectionNode類、ActionNode類和DistanceNode類,非終結符運算式expression和composite對應SentenceNode類和AndNode類。 我們可以通過抽象文法樹來表示具體解釋過程,例如機器人控制指令“
24.3 完整解決方案 為了實現打折演算法的複用,並能夠靈活地向系統中增加新的打折方式,Sunny軟體公司開發人員使用原則模式對電影院打折方案進行重構,重構後基本結構24-2所示: 在圖24-2中,MovieTicket充當環境類角色,Discount充當抽象策略角色,StudentDiscount、ChildrenDiscount和VIPDiscount充當具體策略角色。完整代碼如下所示://電影票類:環境類class MovieTicket {private
22.6 觀察者模式與MVC 在當前流行的MVC(Model-View-Controller)架構中也應用了觀察者模式,MVC是一種架構模式,它包含三個角色:模型(Model),視圖(View)和控制器(Controller)。其中模型可對應於觀察者模式中的觀察目標,而視圖對應於觀察者,控制器可充當兩者之間的中介者。當模型層的資料發生改變時,視圖層將自動改變其顯示內容。22-7所示:圖22-7 MVC結構
18.5 再談Context的作用 在解譯器模式中,環境類Context用於儲存解譯器之外的一些全域資訊,它通常作為參數被傳遞到所有運算式的解釋方法interpret()中,可以在Context對象中儲存和訪問運算式解譯器的狀態,向運算式解譯器提供一些全域的、公用的資料,此外還可以在Context中增加一些所有運算式解譯器都共有的功能,減輕解譯器的職責。 在上面的機器人控製程序執行個體中,我們省略了環境類角色,下面再通過一個簡單一實例來說明環境類的用途:
24.4 策略模式的兩個典型應用 策略模式實用性強、擴充性好,在軟體開發中得以廣泛使用,是使用頻率較高的設計模式之一。下面將介紹策略模式的兩個典型應用執行個體,一個來源於Java SE,一個來源於微軟公司推出的示範項目PetShop。 (1) Java SE的容器布局管理就是策略模式的一個經典應用執行個體,其基本結構24-3所示:【每次看到這個LayoutManager2介面,我都在想當時Sun公司開發人員是怎麼想的!】 在Java
面板模式是使用頻率最高的結構型設計模式之一,無論是在Web應用軟體或是案頭應用軟體,還是在行動裝置 App軟體中,面板模式都得到了廣泛的應用。
偶準備近期寫一本《設計模式實踐指南》,非教材,通俗讀物,文字相對較為輕鬆,面向一線開發人員和模式自學者,大概300頁左右(定價控制在40以內,),現向廣大XDJM們徵集一些意見和建議: 1. 程式設計語言?C#、Java還是C++,如果完全和語言無關,執行個體代碼可能會不完整。 2.
在通用的面板模式結構圖中,如果需要增加、刪除或更換與外觀類互動的子系統類,必須修改外觀類或用戶端的原始碼,這將違背開閉原則,因此我們可以通過引入抽象外觀類來對系統進行改進,在一定程度上解決該問題。在引入抽象外觀類之後,用戶端可以針對抽象外觀類進行編程,對於新的業務需求,不需要修改原有外觀類,而對應增加一個新的具體外觀類,由新的具體外觀類來關聯新的子系統對象,同時通過修改設定檔來達到不修改任何原始碼並更換外觀類的目的。引入抽象外觀類的面板模式結構4所示:圖4
關於金庸小說中到底是招式重要還是內功重要的爭論從未停止,我們在這裡並不分析張無忌的九陽神功和令狐沖的獨孤九劍到底哪個更厲害,但我想每個武林人士夢寐以求的應該是既有淋漓的招式又有深厚的內功。看到這裡大家可能會產生疑問了?搞什麼,討論什麼招式與內功,我只是個軟體開發人員。別急,正因為你是軟體開發人員我才跟你談這個,因為我們的軟體開發技術也包括一些招式和內功:Java、C#、C++等程式設計語言,Eclipse、Visual