在系統開發中,通常都會採用經典的三層或者四層架構。其中資料模型層通過ORM工具來產生模型代碼,實現了資料庫操作的CRUD方法,上層的業務層進行簡單的封裝,供介面層調用。但由於模型層是與資料庫中的單個表對應,而很多資料模型之間是有關聯和上下級關係的,如果僅僅對業務層做簡單封裝,作為傳值和分層之用,則很可能在開發和維護中出現以下問題:
1. 上層介面在增加和修改資料時,需要維護資料之間的關聯和上下級關係;
2.上層介面調用刪除等操作時,需要處理串聯刪除相關資料;
3.上層介面在操作某個資料的下級菜單時,通常要重新擷取,增加了資料庫訪問次數;
4.上層介面在根據使用者選擇的資料來控制操作菜單時,需要重新載入許可權資訊,進行複雜的許可權判斷;
5.通常的資料修改操作都需要記錄日誌,則介面層有大量的日誌記錄代碼;
6.在進行排序和移出(移進)操作時,需要大量代碼來實現。
以上問題是我在C/S結構的應用程式開發中親身經曆過的,不知是否具有普遍性。於是,希望業務層能封裝上述問題相關的“附加”資訊,希望達到以下效果:
1.能夠在移出(移進)時能自動判斷兩個資料之間是否支援該操作;
2.在常用的排序中業務對象能自我排序;
3.在使用者選中某個資料時,能識別出使用者權限,從而控制介面菜單;
4.將日誌的操作封裝成統一介面,並在資料修改發生時業務層自動記錄,上層操作不知道日誌記錄;
5.將系統中的各類資料抽象成統一的資源介面。
按照以上的需求,對業務層進行了點兒封裝,基本上達到了上述的幾個需求,同時其它開發人員在調用過程中感覺到很順手和舒服,代碼量也減少很多,便於系統的升級和維護,上層調用程式碼範例如下:
//將當前選中資料按名稱排序
IDataResource resource = resPad.GetSelectedResource();
if (resource == null)
return;
resource.SortByName();
resPad.RefreshNode(resource);
//許可權判斷
IDataResource resource = resPad.GetSelectedResource();
if (resource != null && !resource.ReadOnly)
{
resource.Update();
}
//資料移出
smDatasetDirectory dir = treeRes as smDatasetDirectory;
foreach (ListViewItem item in this.listViewUngroup.SelectedItems)
{
IDataResource res = item.Tag as IDataResource;
dir.MoveOut(res);
}
//刪除被選中資料資源及其下級
IDataResource resource = resPad.GetSelectedResource();
resource.Delete();
//添加資料
smLayer layerLogic = new smLayer("layer1");
mapLogic.AddResource(layerLogic);
示意類圖如下:
主要類圖:
設計要點:
1.所有業務對象都是資料資源(甚至包括使用者和角色等),統一實現頂級介面;
2.頂級的虛基類實現大部分通用功能(比如日誌記錄和排序等),各業務對象只關心自身的特別業務;
3.業務對象除了包含模型資料,應該是自我描述的,標識自身資料資源的類型,具有許可權資訊;
4.業務對象自身知道能夠與哪些對象發生關係,比如是否能移到某個資源下;
5.業務對象能夠知道自己的上級資源是哪個,下級資源是哪些;
6.當業務對象被執行某種資料庫操作時,應該能自動記錄下相關動作記錄,不必由上層調用來關心日誌。
以上是我的一點兒設計實踐,歡迎大家拍磚!
代碼下載:BusinessLogicCommon_src.rar