Model:
模型層,封裝業務實體,一般和數據庫模式對應。
例如:
public class AccountInfo {
// Internal member variables
private string _userId;
private string _password;
private string _email;
private AddressInfo _address;
private string _language;
private string _category;
private bool _showFavorites;
private bool _showBanners;
。。。
}
IDAL:
數據訪問接口層,主要是一些dao接口。
例如:
public interface IAccount
{
AccountInfo SignIn(string userId, string password);
AddressInfo GetAddress(string userId);
void Insert(AccountInfo account);
void Update(AccountInfo Account);
}
oracleDAL:
oracle實現的數據訪問層。
SQLServerDAL:
sql實現的數據訪問層。
oracleDAL和SQLServerDAL中的類都實現了IDAL中的接口。屬於dao實現。
DALFactory
負責確定是使用oracle實現還是mssql實現。通過在web.config中的配置確定使用哪一個dal實現(通過反射,動態生成訪問類是PetShop.SQLServerDAL還是PetShop.OracleDAL命名空間中的類)。
<add key="WebDAL" value="PetShop.SQLServerDAL"/>
<add key="OrdersDAL" value="PetShop.SQLServerDAL"/>
public class Account
{
public static PetShop.IDAL.IAccount Create()
{
/// Look up the DAL implementation we should be using
string path = System.Configuration.ConfigurationSettings.AppSettings["WebDAL"];
string className = path + ".Account";
// Using the evidence given in the config file load the appropriate assembly and class
return (PetShop.IDAL.IAccount) Assembly.Load(path).CreateInstance(className);
}
}
BLL:
業務訪問層。通過DALFactory,讀取配置,決定使用何種dal實現。
public class Account {
public AccountInfo SignIn(string userId, string password) {
if ((userId.Trim() == string.Empty) || (password.Trim() == string.Empty))
return null;
// 通過DALFactory調用具體的dal實現。
IAccount dal = PetShop.DALFactory.Account.Create();
// Try to sign in with the given credentials
AccountInfo account = dal.SignIn(userId, password);
// Return the account
return account;
}
。。。
}
Web:
表現層,主要包括了Web 頁面(aspx)和用戶控件(ascx)控件及自定義服務器控件SimplePager和ViewStatePager。
Utility:
公用模塊,一組幫助器類,其他業務層和數據訪問層可能會使用到的一些公用方法。
分層如何使系統更靈活
學習面向對象設計和設計模式和架構模式,我們可以知道,設計的重要目的,一個是可重用,一個是可維護還有就是可擴展性。
面向對象技術本身就提供了很多可重用得機制,通過繼承和組合可以使代碼較大程度的重用。另外,我們需要通過設計,抽象出基本的概念,對這些概念進行重用。重用可以提高系統的可維護性,因爲重用的東西一般經過了充分的測試和長時間的考驗,比我們自己重複發明的輪子的質量更容易保證。
可擴展,繼承和重載是擴展的方式,但他們是語言級的,我們需要通過設計達到系統級的可擴展。
這裏主要結合petshop的分層設計和實現談一下這幾個設計的指標。
上面介紹了各個層,各層的調用關係是這樣的:
web層-->BLL(使用Model)-->DALFactory(通過IDAL)-->具體DAL實現層(oracle或ms sql)-->持久存儲。
這樣,各層至於相鄰的層交互,通過定義良好的接口,層內部的實現對其他層來說關係是不大的。這很符合軟件工程的思想,因爲定義好了接口後,開發人員就可以按照自己的特長實現各自的層,並且容易測試,因此可以提高軟件的開發效率和開發質量。
從架構和源碼實現上我們可以看到,數據層的靈活性,可擴展性和可維護性是通過DALFactory層實現的。我們知道,由於採用面向接口編程這一原則, DALFactory可以通過配置文件信息來確定使用哪一個IDAL實現,這樣我們就可以在部署時通過修改配置文件來適應客戶的數據庫要求。當然這也要求,具體的數據庫實現層要遵循特定的命名約定,比如對於Account實現,sql和oracle中對應的類要有相同的名字和構造函數(現在是必須有默認構造函數,否則無法初始化),當然所在的名稱空間要不同。
以後,當我們需要實現mysql或db2的數據實現層的時候,我們只需要通過mysql 或db2按照上面的命名約定實現,在web.config文件中進行配置就可以了(可擴展和可維護性)。而且,如果客戶原先使用mssql後來要使用 oracle,然後…… 如此反覆的折騰,我們也不會撓頭,因爲我們原先的實現可重用,新的要求,可擴展。另一方面,對於同一個數據庫我們也可以採用不同的實現方法,比如 ado.net(又分爲直接的sql和存儲過程實現),orm框架,ibati式的半orm框架,我們可以爲每種這樣的實現建立一個工程,靈活的選擇,而不是僅在原來的基礎上修改。這就是petshop數據訪問層向我們展示的爲什麼要這麼分層。
其實現在的很多框架和系統爲了實現靈活性都是通過配置實現的,因爲修改配置
不像修改源代碼那樣需要重新發布,而且就像petshop,OracleDAL,SQLServerDAL的兩個dll可以同時存在,需要使用哪一個就配置哪一個就可以了。
最近了一下ibatis的DataAccess,其實DataAccess就是一個DAO框架,它是通過在xml文件中配置和要求客戶建立dao接口(也就是petshop中IDAL)來將上層BLL和DAL實現層解耦的。所以思想都是一樣的。