說明一下,原本的思路是通過一步一步教你使用AgileEAS.NET基礎類庫進行應用開發-系列目錄相關的文章來逐步講解基於AgileEAS.NET平台進行應用開發的文章,但是在進行案例講解的過程,我們不得不扯到有關於AgileEAS.NET平台進行應用開發的架構設計方面的東西,我就把一些與架構有關的文章分離出來講,了,我是基於AgileEAS.NET平台的應用開發執行個體來講解架構設計,所以本文應該還有個副標題“一步一步教你使用AgileEAS.NET基礎類庫進行應用開發-基礎篇-提取獨立的業務層”,如果可能的話我會在這些獨立抽取出來的文章的基礎上,來個執行個體講解DotNET企業架構應用實踐方面的系列。
系列回顧
在前面的文章中,我從統一資料訪問開始講起,通過UDA到ORM的一步一步的深入,我們講到了應用系統開發架構之中的資料訪問層,並且詳細的講解了基於介面驅動的資料層,一步一步教你使用AgileEAS.NET基礎類庫進行應用開發-基礎篇-基於介面驅動的資料層一文中我提到了以下的分層模型:
但是在嚴格意義上講,我們之前一直在講資料訪問層的東西,示範的例子中並完成擁有獨立的商務邏輯層,整體結構如下:
關於業務層
業務層是實現應用商務邏輯處理的商務邏輯層(Business Logic Layer,我們簡稱為BLL或者BL,從系統架構的理論角度講,商務邏輯處理存在於任何架構的系統,我們把這些處理商務邏輯的代碼獨立抽取出來則形成獨立業務層。
那麼,業務層到底是做什麼呢,在基於資料庫支援的管理資訊系統中,其大多採用的是UI-->BL-->DAL這樣的基準分層架構或者基於這種基準架構的擴充,如UI-->BL-Agent—>BL->DAL或者UI-->BL-Agent->SL-Agent—>SL—>BL->DAL等等結構。
在於UI-->BL-->DAL這種分層結構的系統之中,業務層使用DAL層提供的資料訪問服務封裝商務邏輯以供UI層使用,也就是可以簡單的理解為,業務層把UI要求的業務處理進行轉化並使用DAL層提供的服務按商務程序進行處理。
現在的問題
現在我們回家看我們前面示範的例子,我們的例子中只分解了UI(ClassLib.OrmDemo)和DAL層(ClassLibDemo.DAL.Interface、ClassLibDemo.DAL.SQLServer),那麼是不是我們沒有商務邏輯呢,這倒不是,只不過,商務邏輯被分解到DAL和UI層之中了,因為在DAL層中的資料對象之中已經預設提供了資料業務處理的CRUD,也算是一種業務處理,複雜一些的業務,如產品入庫處理這樣的業務我們則由程式員自己編寫,並且增加在產生的DAL代碼之中的部分類別之中。
當然對於一個很簡單的應用,我們這樣處理是一種選擇,如果這個應用很複雜,我們採用這種結構則會顯得代碼結構有點混亂,我們有必要提出獨立的商務邏輯層(BL)。
結構的變化
現在我們需要在原有解僱方案之中增加一個項目ClassLibDemo.BL,則項目結構變成如下:
在ClassLib.OrmDemo和ClassLibDemo.DAL.Interface之中增加一個項目ClassLibDemo.BL,其職責是完成除ORM對象CRUD之外的業務,從我們也可以看出ClassLib.OrmDemo也有跨過ClassLibDemo.BL對ClassLibDemo.DAL.Interface的直接調用。
關於此問題有一個爭論,那就是ORM對象應該是獨立的儲存物件還是具有一定的業務功能,如,Insert、Update、Delete,我們估且不討論這個,在目前的AgileEAS.NET平台中,ORM對象含有這些商務邏輯功能。
基於以上原因,在基於AgileEAS.NET平台的應用開發中,業務層的職責是處理除ORM對象CRUD之外的業務,也就是複雜的商務邏輯。
變更代碼
現在我就商品入庫業務示範一下業務的變更,首先我們注釋或者刪除ClassLibDemo.DAL.Interface項目中介面IProductInList的方法ProductIn定義,同時刪除ClassLibDemo.DAL.SQLServer中相關的代碼,在ClassLibDemo.BL中增加一個類ProductInBL,代碼如下:
1 public class ProductInBL:EAS.Business.BusinessObject
2 {
3 /// <summary>
4 /// 產品入庫業務。
5 /// </summary>
6 /// <param name="pInList"></param>
7 public void ProductIn(IProductInList pInList)
8 {
9 this.DataAccessor.TransactionExecute(new TransactionHandler2(this.InternalIn), pInList);
10 }
11
12 void InternalIn(IDataAccessor accessor, params object[] parameters)
13 {
14 IProductStore pStore = DALHelper.DALManager.CreateProductStore();
15 pStore.DataAccessor = accessor;
16
17 IProductInList pInList = parameters[0] as IProductInList; //通過參數取值。
18
19 foreach (IProductIn pIn in pInList.Rows)
20 {
21 pIn.DataAccessor = accessor;
22 pIn.Idn = pIn.GetMaxNewIdn();
23 pIn.Insert();
24
25 pStore.Code = pIn.Code;
26 pStore.Price = pIn.Price;
27 pStore.Refresh();
28
29 if (pStore.Exists)
30 {
31 pStore.Number += pIn.Number;
32 pStore.Update();
33 }
34 else
35 {
36 pStore.Idn = pStore.GetMaxNewIdn();
37 pStore.Code = pIn.Code;
38 pStore.Name = pIn.Name;
39 pStore.Spec = pIn.Spec;
40 pStore.Unit = pIn.Unit;
41 pStore.Price = pIn.Price;
42 pStore.Number = pIn.Number;
43 pStore.Insert();
44 }
45 }
46 }
47 }
我們修改UI項目中入庫業務調用的代碼ProductInDemo如下:
1 class ProductInDemo
2 {
3 public void ProductIn1()
4 {
5 this.ProductIn2();
6 }
7
8 public void ProductIn2()
9 {
10 IProductInList pInList =DALHelper.DALManager.CreateProductInList();
11
12 IProduct dict =DALHelper.DALManager.CreateProduct();
13 dict.Code = "1AZ0002094";
14 dict.Refresh();
15
16 IProductIn pIn =DALHelper.DALManager.CreateProductIn();
17 pIn.Code = dict.Code;
18 pIn.Name = dict.Name;
19 pIn.Spec = dict.Spec;
20 pIn.Unit = dict.Unit;
21 pIn.Price = 12.8M;
22 pIn.Number = 200;
23
24 pIn.InTime = DateTime.Now;
25 pIn.BillCode = DateTime.Now.ToString("yyyyMMddHHmmss") + "_1";
26 pIn.Operator = "james-orm";
27 pInList.Rows.Add(pIn);
28
29 try
30 {
31 new ProductInBL().ProductIn(pInList);
32 System.Console.WriteLine("入庫處理完成。");
33 }
34 catch
35 {
36 System.Console.WriteLine("入庫未完成。");
37 }
38 }
39 }
最後編譯運行:
有關本例子所涉及的資料表結構請參考基於AgileEAS.NET平台基礎類庫進行應用開發-總體說明及資料定義一文,有關資料物件模型定義檔案、文檔、DDL指令碼請下載:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代碼下載:BL.Demo1.rar。
連結
一步一步教你使用AgileEAS.NET基礎類庫進行應用開發-系列目錄
AgileEAS.NET平台開發指南-系列目錄
AgileEAS.NET應用開發平台介紹-文章索引
AgileEAS.NET平台應用開發教程-案例計劃
AgileEAS.NET官方網站
敏捷軟體工程實驗室
QQ群:116773358