1.問題描述
<b>設計并實作一個軟體系統</b>。要求如下:
主要功能如下圖所示:

該軟體系統由指令行指定要進行處理的英文文本檔案(.txt)的目錄和檔案名以及輸出結果檔案的目錄和檔案名。
2.解決方案:
a.面向過程方案:
評價:這種是最簡陋的實作,可擴充性不強,不過程式倒也簡單明了。
b.基本面向對象方案:
該方案是個基本的面向對象方案,有四個基本功能類:input, shift, alphabetize 和 output,将這些功能在主程式中串聯起來,通過共享資料的方式組成整個系統。
流程很簡單,首先通過input類設定檔案輸入輸出路徑并且讀入要處理的檔案,接着使用shift進行移位操作,得到一行行的結果,此時再采用alphabetizer對這些行進行首字母排序,最後采用output類輸出。
設計了一個Kwic類對上述類進行整合。提供代碼:
<a href="http://cid-a0a0b50959052db4.skydrive.live.com/self.aspx/.Public/KWIC%5E_Routine.zip">http://cid-a0a0b50959052db4.skydrive.live.com/self.aspx/.Public/KWIC^_Routine.zip</a>
評價:将各個功能子產品分開設計,并且利用權限控制保證了封裝的特性,系統的擴充性和封裝性增強。
c.基于事件通知的方案:
基于事件通知的系統中的各個功能并不是直接被調用的,而是通過組建通知或廣播事件資訊而觸發的。其他元件可以通過注冊一個與某個事件通知相關聯的過程而與其發生聯系。例如,我們的IDE就是一個典型的這樣的系統,編輯器和變量螢幕與調試器的斷點功能相聯系,當調試器停留在某一個斷點的時候,它就會自動去通知與其注冊的元件,去定位代碼或者觀察變量的取值。
一般這樣的方案有兩種設計,一個是系統有一個分立出來的事件中心,專門負責接收所有傳來的資訊,并且将它們分發給系統的其他元件,它可以是廣播,可以是針對某些特定事件而設定特定的反應。
這常被稱為:Publish/Subscribe,如下圖
一種方案不設定一個集權的事件中心,每個子產品允許其他子產品在他們發送的消息中聲明他們需要幹什麼,這樣每次子產品發送的消息都隻發送給對這個事件感興趣的子產品去,而無需發送到事件中心。
這常被稱為:Observable/Observer,如下圖
在KWIC這個系統中,我們如此實作這個基于事件的系統:
兩個行存儲子產品,第一個行存儲子產品負責存儲所有原先的行,第二個行存儲子產品負責存儲是以循環移位後的子產品。 輸入子產品負責設定路徑并且從輸入檔案中讀入并且存儲到第一個行存儲子產品中。 循環移位子產品負責循環移位并且存儲在第二個行存儲子產品。輸出子產品負責輸出到檔案,主要子產品負責主要流程。添加一行到第一個行存儲子產品就觸發了一個事件向循環移位子產品發送,循環移位子產品會根據這個事件對這一行就行處理,存儲到第二個行存儲子產品,這就會另一個事件發送到排序子產品,子產品會把新加進來的行與舊行進行混合然後排序。 實作的是Observable/Observers模式,其中的事件互動有兩部分:
移位循環子產品和第一個行存儲子產品注冊。移位子產品是第一個行存儲子產品的觀察者。 排序子產品注冊和第二個行存儲子產品注冊。排序子產品是第二個行存儲子產品的觀察者。
Java對這樣的模式提供Observable 類和Observer接口,
在java.util中的Observer接口為觀察者提供了友善,隻有一個方法需要實作:update。這個方法在當接到事件時被觸發。
在java.util中的Observable類為發送事件的類提供了友善,我們可以通過繼承而是用其提供了其他類向觀察者注冊的方法。
d.基于管道的方案
在基于管道的方案中,每個元件都會有一組輸入流和一組輸出流,一個元件讀入,然後處理後送出到下一個元件上。這個元件一般稱為filter。連接配接器則稱為pipes。filter之間不能有資料共享,并且彼此互相獨立。最有名的類似的程式就是Unix的Shell了。
<a href="http://cid-a0a0b50959052db4.skydrive.live.com/self.aspx/.Public/kwic%5E_pipe.zip">http://cid-a0a0b50959052db4.skydrive.live.com/self.aspx/.Public/kwic^_pipe.zip</a>