循序漸進(jìn)開發(fā)WinForm項(xiàng)目(2)--項(xiàng)目代碼的分析

隨筆背景:在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉(zhuǎn)到C#開發(fā)的晰奖,有沒有一些基礎(chǔ)性的資料給我們學(xué)習(xí)學(xué)習(xí)呢谈撒,你的框架感覺一下太大了,希望有個循序漸進(jìn)的教程或者視頻來學(xué)習(xí)就好了匾南。
其實(shí)也許我們每天面對的太多東西了啃匿,覺得很多都稀松平常了,即使很細(xì)微的地方午衰,可能我們都已經(jīng)形成習(xí)慣了立宜。反過來,如果我們切換到其他領(lǐng)域臊岸,如IOS橙数、android,那么開始我們可能對里面很多設(shè)計(jì)的規(guī)則不甚了解帅戒,開始可能也是一頭霧水灯帮。
本篇繼續(xù)上一篇《循序漸進(jìn)開發(fā)WinForm項(xiàng)目(1) --數(shù)據(jù)庫設(shè)計(jì)和項(xiàng)目框架的生成》,繼續(xù)介紹如何循序漸進(jìn)開發(fā)Winform項(xiàng)目逻住,繼續(xù)分析介紹Winform的項(xiàng)目代碼钟哥,從而讓我們更加了解其中的分層和項(xiàng)目框架的組成等內(nèi)容。

1瞎访、數(shù)據(jù)訪問接口的定義

上面我們分析了實(shí)體類的定義腻贰,本節(jié)繼續(xù)分析其他部分的內(nèi)容,如數(shù)據(jù)訪問接口成的定義如下所示扒秸。

namespace WHC.TestProject.IDAL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public interface ICustomer : IBaseDAL<CustomerInfo>
    {
    }
}

這里面的代碼很簡單播演,沒有多余的代碼行,那么里面究竟發(fā)生了什么呢伴奥,其中的IBaseDAL又是什么定義呢写烤?



其實(shí),IBaseDAL就是定義了很多我們開發(fā)用到的基礎(chǔ)接口拾徙,如標(biāo)準(zhǔn)的增刪改查洲炊,以及衍生出來的一些其他接口,如分頁查詢尼啡,條件查詢等接口內(nèi)容暂衡。這個ICustomer就是用來定義一些除了標(biāo)準(zhǔn)接口不能實(shí)現(xiàn)外的業(yè)務(wù)接口。
IBaseDAL通過傳入一個實(shí)體類玄叠,從而方便給基類接口提供強(qiáng)類型的數(shù)據(jù)類型指定古徒,提高我們的開發(fā)效率,減少出錯的機(jī)會读恃。
我們可以在VS里面查看IBaseDAL的定義隧膘,如下所示:



可以看到里面很多相關(guān)的接口定義,有返回實(shí)體T的寺惫,也有返回List<T>的疹吃,還有DataTable類型等等,這些基礎(chǔ)接口西雀,經(jīng)過我們多個項(xiàng)目的應(yīng)用實(shí)踐萨驶,已逐步穩(wěn)定并能夠提供很好的接口支持,方便我們快速調(diào)用處理艇肴。
即使我們在沒有實(shí)現(xiàn)任何業(yè)務(wù)接口的情況下腔呜,僅僅利用標(biāo)準(zhǔn)的基類API叁温,也基本上能夠完成絕大多數(shù)的數(shù)據(jù)操作功能了。

2核畴、數(shù)據(jù)訪問接口實(shí)現(xiàn)類的定義

我們分析完IDAL的數(shù)據(jù)訪問接口成的定義后膝但,繼續(xù)了解一下,如何基于這個接口進(jìn)行訪問層的實(shí)現(xiàn)設(shè)計(jì)的谤草。數(shù)據(jù)訪問的實(shí)現(xiàn)層在項(xiàng)目中的位置如下所示(以基于SqlServer的DALSQL層進(jìn)行分析)跟束。



它的類代碼定義如下所示。

namespace WHC.TestProject.DALSQL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public class Customer : BaseDALSQL<CustomerInfo>, ICustomer
    {

數(shù)據(jù)訪問接口實(shí)現(xiàn)層和接口定義層一樣丑孩,都有一個基類冀宴,如基于SqlServer實(shí)現(xiàn)的基類為BaseDALSQL,這個基于SqlServer的數(shù)據(jù)訪問基類温学,它也是繼承自一個超級基類(大多數(shù)的實(shí)現(xiàn)在這里)AbstractBaseDAL略贮。他們之間的繼承關(guān)系如下所示



而我們剛才在項(xiàng)目工程的圖里面看到,BaseDALSQL枫浙、IBaseDAL刨肃、AbstractBaseDAL這些類庫由于具有很大的通用性,為了減少在不同的項(xiàng)目中進(jìn)行復(fù)制導(dǎo)致維護(hù)問題箩帚,因此我們?nèi)堪堰@些經(jīng)常使用到的基類或者接口真友,抽取到一個獨(dú)立的類庫里面,為了和普通的DotNET公用類庫命名進(jìn)行區(qū)分(WHC.Framework.Commons)紧帕,我們把它命名為WHC.Framework.ControlUtil盔然。
BaseDALSQL基類的定義如下所示。



這樣做的好處是是嗜,在所有的模塊里面愈案,避免復(fù)制導(dǎo)致的版本維護(hù)問題,同時也減少代碼的重復(fù)生成鹅搪,增量生成的全部代碼站绪,可以一次性復(fù)制到整個項(xiàng)目工程里面,而不會導(dǎo)致基礎(chǔ)類庫的替換丽柿,因?yàn)檫@些基類不在生成目錄里面恢准,所有生成的類文件,都是和業(yè)務(wù)表相關(guān)的甫题,如下所示馁筐。

具體的數(shù)據(jù)訪問實(shí)現(xiàn)類(如Customer),它把數(shù)據(jù)庫信息轉(zhuǎn)換為實(shí)體類坠非,有一個函數(shù)敏沉,在代碼生成的時候已經(jīng)生成;同時在把實(shí)體類的屬性保存到數(shù)據(jù)庫也有一個類似CRM的映射關(guān)系,從而實(shí)現(xiàn)可空的字段獲取和更新操作盟迟。

/// <summary>
/// 將DataReader的屬性值轉(zhuǎn)化為實(shí)體類的屬性值秋泳,返回實(shí)體類
/// </summary>
/// <param name="dr">有效的DataReader對象</param>
/// <returns>實(shí)體類對象</returns>
protected override CustomerInfo DataReaderToEntity(IDataReader dataReader)
{
    CustomerInfo info = new CustomerInfo();
    SmartDataReader reader = new SmartDataReader(dataReader);
    
    info.ID = reader.GetString("ID");
    info.Name = reader.GetString("Name");
    info.Age = reader.GetInt32("Age");
    info.Creator = reader.GetString("Creator");
    info.CreateTime = reader.GetDateTime("CreateTime");
    
    return info;
}

/// <summary>
/// 將實(shí)體對象的屬性值轉(zhuǎn)化為Hashtable對應(yīng)的鍵值
/// </summary>
/// <param name="obj">有效的實(shí)體對象</param>
/// <returns>包含鍵值映射的Hashtable</returns>
protected override Hashtable GetHashByEntity(CustomerInfo obj)
{
    CustomerInfo info = obj as CustomerInfo;
    Hashtable hash = new Hashtable(); 
    
    hash.Add("ID", info.ID);
     hash.Add("Name", info.Name);
     hash.Add("Age", info.Age);
     hash.Add("Creator", info.Creator);
     hash.Add("CreateTime", info.CreateTime);
         
    return hash;
}

3、業(yè)務(wù)邏輯層的實(shí)現(xiàn)分析

分析完成了數(shù)據(jù)訪問層的接口和實(shí)現(xiàn)類后攒菠,我們來進(jìn)一步看看業(yè)務(wù)邏輯層的實(shí)現(xiàn)分析轮锥,由于數(shù)據(jù)訪問層的本意是基于特定的數(shù)據(jù)庫實(shí)現(xiàn),因此業(yè)務(wù)邏輯層就是抽象不同的數(shù)據(jù)庫要尔,讓它們根據(jù)配置,指向不同的數(shù)據(jù)庫實(shí)現(xiàn)類新娜,從而實(shí)現(xiàn)多數(shù)據(jù)庫的支持赵辕。

namespace WHC.TestProject.BLL
{
    /// <summary>
    /// 客戶信息
    /// </summary>
    public class Customer : BaseBLL<CustomerInfo>
    {
        public Customer() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
        }
    }
}

業(yè)務(wù)邏輯層的代碼也很簡單,在構(gòu)造函數(shù)里面Init一下即可概龄,之所以使用這個Init操作还惠,其實(shí)為了確定BLL層的業(yè)務(wù)對象名稱和指定在哪個程序集里面進(jìn)行構(gòu)造的需要,讓給基類進(jìn)行必要的創(chuàng)建工作私杜。

在BaseBLL的Init函數(shù)里面蚕键,我們根據(jù)子類傳入的相關(guān)參數(shù),由于我們約定了數(shù)據(jù)訪問類的命名空間衰粹,因此只根據(jù)數(shù)據(jù)庫配置的不同需要锣光,替換部分名稱,就可以具體的構(gòu)造出一個數(shù)據(jù)訪問類了铝耻。

#region 根據(jù)不同的數(shù)據(jù)庫類型誊爹,構(gòu)造相應(yīng)的DAL層
AppConfig config = new AppConfig();
string dbType = config.AppConfigGet("ComponentDbType");
if (string.IsNullOrEmpty(dbType))
{
    dbType = "sqlserver";
}
dbType = dbType.ToLower();

string DALPrefix = "";
if (dbType == "sqlserver")
{
    DALPrefix = "DALSQL.";
}
else if (dbType == "access")
{
    DALPrefix = "DALAccess.";
}
else if (dbType == "oracle")
{
    DALPrefix = "DALOracle.";
}
else if (dbType == "sqlite")
{
    DALPrefix = "DALSQLite.";
}
else if (dbType == "mysql")
{
    DALPrefix = "DALMySql.";
}
#endregion

this.dalName = bllFullName.Replace(bllPrefix, DALPrefix);//替換中級的BLL.為DAL.,就是DAL類的全名
baseDal = Reflect<IBaseDAL<T>>.Create(this.dalName, dalAssemblyName);//構(gòu)造對應(yīng)的DAL數(shù)據(jù)訪問層的對象類

這樣精確構(gòu)造出來的數(shù)據(jù)庫訪問訪問對象瓢捉,并把它轉(zhuǎn)換為基類接口频丘,那么就可以在BaseBLL類里的基類接口進(jìn)行調(diào)用了。
而構(gòu)造業(yè)務(wù)對象泡态,通過BLLFactory<T>的泛型工廠搂漠,更能夠精確構(gòu)造出對應(yīng)的業(yè)務(wù)對象類,這樣構(gòu)造出來的對象具有強(qiáng)類型某弦,非常方便使用桐汤。


以上就是業(yè)務(wù)邏輯層,數(shù)據(jù)訪問層和數(shù)據(jù)訪問接口層的設(shè)計(jì)關(guān)系刀崖,為了高效進(jìn)行開發(fā)工作惊科,我們一定要使用強(qiáng)類型的接口調(diào)用,這樣可以大大減少出錯機(jī)會亮钦,而返回的基類接口馆截,由于傳入了特定的具體類型T,也能夠構(gòu)造出強(qiáng)類型的列表或者對象。因此蜡娶,合理利用泛型混卵,能夠是我們的開發(fā)體驗(yàn)更加美好,更加高效窖张。
循序漸進(jìn)開發(fā)WInform項(xiàng)目--系列文章導(dǎo)引:
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(6)--開發(fā)使用混合式Winform模塊
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(5)--Excel數(shù)據(jù)的導(dǎo)入導(dǎo)出操作
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(4)--Winform界面模塊的集成使用
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(3)--Winform界面層的項(xiàng)目設(shè)計(jì)
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(2)--項(xiàng)目代碼的分析
循序漸進(jìn)開發(fā)WinForm項(xiàng)目(1) --數(shù)據(jù)庫設(shè)計(jì)和項(xiàng)目框架的生成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幕随,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宿接,更是在濱河造成了極大的恐慌赘淮,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睦霎,死亡現(xiàn)場離奇詭異梢卸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)副女,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門蛤高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碑幅,你說我怎么就攤上這事戴陡。” “怎么了沟涨?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵恤批,是天一觀的道長。 經(jīng)常有香客問我裹赴,道長开皿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任篮昧,我火速辦了婚禮赋荆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘懊昨。我一直安慰自己窄潭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布酵颁。 她就那樣靜靜地躺著嫉你,像睡著了一般。 火紅的嫁衣襯著肌膚如雪躏惋。 梳的紋絲不亂的頭發(fā)上幽污,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音簿姨,去河邊找鬼距误。 笑死簸搞,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的准潭。 我是一名探鬼主播趁俊,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刑然!你這毒婦竟也來了寺擂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤泼掠,失蹤者是張志新(化名)和其女友劉穎怔软,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體择镇,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爽雄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了沐鼠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡叹谁,死狀恐怖饲梭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焰檩,我是刑警寧澤憔涉,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站析苫,受9級特大地震影響兜叨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衩侥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一国旷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茫死,春花似錦跪但、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爱榔,卻和暖如春被环,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背详幽。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工筛欢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓悴能,卻偏偏與公主長得像揣钦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子漠酿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容