在這次專案開發實踐中,我又一次嘗試用Python指令碼生成C#程式碼,其效果讓我很滿意 -- 提高了程式碼質量,可維護性和工作效率;同時降低了出錯率。
看來事情在向好的方面發展。那麼促成的因素是什麼?我思考了一下,可能有以下2點:
- 在用指令碼生成程式碼方面積累的實踐技術經驗
- 在運用第1點時,讓我感受到了“資料建模”和“框架設計”
回憶這次設計過程,我首先識別了下面幾個部分的資料:
- 前端展示資料
- 業務層資料
- 資料層資料
通過一個Excel表格,將這三層資料定義出來,然後再用指令碼生成程式碼。但是,由於這次的業務不復雜,因此,這三層資料都定義在了一個表格中。
當完成這部分工作之後,再往回看,這個過程不就是資料建模過程嗎?
當表格定義完成後,再根據表格中的定義去寫Python指令碼,生成前端展示層,業務層和資料層的程式碼。而這些生成的程式碼,實際上都是代表特定功能的函式程式碼。
這裡我想到了常見MVC框架,MVC框架不也是提供了一套完整的函式實現了訪問請求和內容展現嗎?實際上再擴大一些,框架做的都是這個事情。
現在,似乎可以得出這個結論:
資料模型 + 框架 = 可執行的系統。
這是一個很簡單的等式,展現在我們眼前的景象是我們的日常開發工作就是把資料模型建好,然後把它們塞進框架中,這樣我們就可以休息了。如果你真的相信這幅景象,那說明你被暫時洗腦了。
在我們的專案中,處處都是包含有成百上千行程式碼的cs檔案,隨便開啟一個儲存過程就有上千行的程式碼,它們是bug的溫床,像噩夢一般時時困擾著我們。那這些程式碼是什麼程式碼?
我認為,這些程式碼可以被分為下面兩種:
- 業務邏輯轉換的程式碼
- 讓框架識別資料的程式碼
業務邏輯轉換的程式碼,最突出的如以下程式碼
條件分支
if (businessType == 'Rental') { .... } else if(businessType == 'Lease') { .... } else { .... }
適配轉換
public string FirstName{get;set;} public string LastName{get;set;} public string FullName{return FirstName + " " + LastName;}
上面的程式碼僅僅反應的業務邏輯。幾乎不涉及任何技術。
讓框架識別資料的程式碼,典型的如下的資料庫訪問
using(var cmd = con.CreateCommand()){ cmd.CommandText = "sp_XXX"; cmd.Parameters.Add(....); using(var reader = cmd.ExecuteReader()) { ... } }
上面的程式碼告訴ADO.net框架,我們要呼叫儲存過程,併為其設定引數。
但是通常的情況下,我們很容易會將上面兩種程式碼混合起來,並很容易認為這是理所當然的。
但是,很快,有人意識到了問題,開發出來了ORM框架,比如NHibernate,Entity Framework等等。這樣,框架識別資料的程式碼變成了下面這樣。
[Table("T_Customer")] public class Customer{ [Column("FIRSTNAME")] public string FirstName{get;set;} ... }
這是一個開始,但不是結束。我們對框架的設計還可以根據業務需要,將框架的設計從技術層面向業務層面推進。
因此現在可以再次回到上面那個等式
資料模型 + 框架 = 可執行的系統
我們可以從這個等式出發,分別從資料模型和框架的角度去設計程式。