今天討論的還是在物件導向的範疇內,因為物件導向的寫法和傳統的有些不同,思維更是不同。
以前在學生或菜鳥階段學程式,基本上都是以程式的流程為主,很少有老師會特別針對程式的組織以及可重覆使用的特性做深入的講解,所以在很多的情況下,程式多半是以流程的方式撰寫,久而久之,程式碼的重覆撰寫率就會很高,而且沒辦法很明確的將程式碼切割成可重覆使用的模組,這當然是習慣使然,只是這樣會令程式很難以維護,例如:
public void listBoxSearch_Click( object sender, EventArgs e )
{
string searchTerm = textBoxSearchTerm.Text;
searchTerm = parseSearchString( searchTerm );
int countryId = listBoxCountry.SelectedValue;
DataTable searchResults =
SearchApplicationDb.GetSearchResults( searchTerm, countryId );
gridSearchResults.DataSource = searchResults;
gridSearchResults.DataBind( );
string searchCriteriaText = getSearchCriteriaText( );
labelCurrentSearch.Text = searchCriteriaText;
}
(Source: 軟體構築美學)
流程導向的程式設計方式,雖然很容易讓人一目瞭然,但是程式碼可重覆使用性卻是最低的,以上面那一段程式為例,只在一個函數中就做掉了資料存取,分析,繫結的工作,導致函數的職責過多,其他的程式碼若是一樣使用相同的邏輯但只修改一點點時,變得必須要做 copy/paste 後,再去修改那一點點差別,時間一長,很多相同卻差距極小的程式碼就會充斥在系統的每個部份,對於可維護性的傷害是非常大的。
昨天我們講了七種不同的物件導向原則,每一個原則不但提高了程式的可重覆使用性,也讓每個函式的內容更容易測試與除錯,間接的影響到程式與系統的品質。所以如果用物件的方式,可以把它改寫成像下列的程式碼:
public void listBoxSearch_Click( object sender, EventArgs e )
{
ISearchUtil searchUtil = SearchApplicationUtilFactory.Create();
gridSearchResults.DataSource =
searchUtil.GetSearchResults(
textBoxSearchTerm.Text, listBoxCountry.SelectedValue);
gridSearchResults.DataSource = searchResults;
gridSearchResults.DataBind( );
labelCurrentSearch.Text = searchUtil.GetSearchCriteriaText( );
}
將搜尋 DB 的工作交由 SearchApplicationFactory 生成的 ISearchUtil 介面的物件來做,這樣這段程式碼就只是負責前端資料收集與呈現,以後其他的程式碼只要用 SearchApplicationFactory 來取得物件,就可以執行一樣的工作,而對 ISearchUtil 物件的修改,馬上可以反應到所有使用它的用戶端程式,而且不需要重新建置。
所以在寫程式時,少一點流程寫法,多一點物件寫法,可以在無形中得到許多的好處,何樂而不為?