.NET 業務架構開發實戰之七 業務層初步構想
前言:本篇主要講述如何把DAL和BLL銜接起來。
本篇議題如下:
1. DAL和BLL之前的Mapping
2. 如何Mapping
3. 再次構思
系列文章連結:
<a href="http://www.cnblogs.com/yanyangtian/archive/2010/05/24/1742432.html">[原創].NET 分布式架構開發實戰之二 草稿設計</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/05/26/1744064.html">[原創].NET 分布式架構開發實戰之三 資料通路深入一點的思考</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/05/28/1746334.html">[原創].NET 分布式架構開發實戰之四 建構從理想和實作之間的橋梁(前篇)</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/05/31/1747811.html">[原創].NET 分布式架構開發實戰五 Framework改進篇</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/03/1750444.html">[原創].NET 業務架構開發實戰之六 DAL的重構</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/07/1752921.html">[原創].NET 業務架構開發實戰之七 業務層初步構想</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/09/1754426.html">[原創].NET 業務架構開發實戰之八 業務層Mapping的選擇政策</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/17/1759327.html">[原創].NET 業務架構開發實戰之九 Mapping屬性原理和驗證規則的實作政策</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/28/1766442.html">[原創].NET 業務架構開發實戰之十 第一階段總結,深入淺出,水到渠成(前篇)</a> <a href="http://www.cnblogs.com/yanyangtian/archive/2010/06/28/1766460.html">[原創].NET 業務架構開發實戰之十 第一階段總結,深入淺出,水到渠成(後篇)</a>
首先,業務類和資料實體類不是一 一對應的關系,換句話說,不是一個業務類就一定對應資料庫中的一張表。業務類是用隻是使用資料實體中的資料而已,是以一個業務類中的資料往往來自多個資料實體。
每個業務類都是有自己的一些屬性的,把資料以資料實體或者DataTable的形式從DAL擷取之後,BLL類就使用這些資料,BLL不會把這些原生的資料實體暴露給UI。BLL類會把UI中要是用的資料裝入到自己的屬性中。
是以在這個過程中就有一個指派的過程,或者稱為mapping映射。當Richard提出這個想法後,項目組的同僚就問他:為什麼要做的這麼複雜,還要一 一 的指派,為什麼不直接把資料實體給UI使用,為什麼一定要在中間這麼轉一下呢?
Richard分析了一些原因:
1. 如果直接把資料實體給了UI,那麼UI那端就很清楚DAL了,以後資料通路方式從ADO.NET 到了EF,那麼UI 就動了,又回到以前了。
2. 在BLL中可以對從DAL取出來的資料進行一些處理,如轉換格式,計算,組合等。
Richard想到把BLL和DAL徹底的解耦:業務類中不存在資料實體類的引用。這樣設計之後靈活性就很大了。最後達到的效果就是:通過配置,配置業務類每個屬性的資料的來源。而這個業務類完全不知道這些資料到底來源于哪個或者哪些資料實體。
這樣确實很靈活,Richard興奮不已。
2. 如何Mapping
初步想法通過配置檔案。如現在有一個Product的業務類,定義如下:

代碼
public class ProductBL
{
public string ProductName { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
那麼如何給這些屬性指派,同時也不引用資料實體。Richard用配置檔案來實作的,這裡Richard就約定了:配置檔案的名字就是“業務類的名字”+“Mapping.xml”.是以Product的配置檔案就是ProductBLMapping.xml

<?xml version="1.0" encoding="utf-8" ?>
<BusinessModel name="ProductBL" mappingTo="DAL.ProductEntity" >
<property name="ProductName" mappingTo="Name" type="System.String"/>
<property name="Price" mappingTo="Price" type="System.Decimal"/>
<property name="Description" mappingTo="Description" type="System.String"/>
</BusinessModel>
然後再運作的時候就通過反射來指派。
現在問題又來了:
1. 每次都是通過反射來指派,性能很成問題。
2. 如果配置檔案出錯,調試很不友善。
3. 如何處理一個業務類對應對個資料實體的情況,如:

public string Description { get; set; }
//來自CustomDAL
public string CustomerName { get; set; }
但是好處很明顯:
1. DAL和BLL解耦
2. 很便于查詢對象的實作。例如:在UI代碼寫:
ICriteria condition=CriteriaFactory.Create(typeof(ProductBL).Where("ProductName", Operation.Equal,"book");
當然ProductName是業務類ProductBL的屬性,在查詢對象最後解析為SQL語句的時候就可以利用ProductBLMapping.xml來生成SQL。
(注:小洋請大家想想,上面的思想來自于.NET中哪個開源架構?)
對于性能方面,Richard嘗試這樣解決:
在第一次Mapping的時候,就把這些mapping的資訊儲存在靜态字典中,下次在mapping的時候,就不用再讀配置檔案了,而且讀記憶體中的字典。
但是這樣,随着業務類的增加,記憶體使用也加大,而且指派方式還是反射。
Richard接着考慮:如何處理一個業務類對應對個資料實體的情況?于是配置檔案就改為了:

<BusinessModel name="ProductBL" >
<property name="ProductName" mappingTo="DAL.ProductEntityName" type="System.String"/>
<property name="Price" mappingTo="DAL.ProductEntityPrice" type="System.Decimal"/>
<property name="Description" mappingTo="DAL.ProductEntityDescription" type="System.String"/>
<property name="CustomerName" mappingTo="DAL.CustomerEntity.Name" type="System.String"/>
基本的問題算是解決了,但是性能的問題依然存在。
Richard又開始考慮更加好的方式。
本篇就寫到這裡,謝謝各位。
下篇:.NET 業務架構開發實戰之八 業務層Mapping的選擇政策