成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

利用General框架進(jìn)行三層架構(gòu)開發(fā)

開發(fā) 架構(gòu)
三層架構(gòu)是企業(yè)信息管理系統(tǒng)中一種比較流行的架構(gòu)方式,如大家所知,三層架構(gòu)將信息系統(tǒng)分為數(shù)據(jù)訪問層(DAL)、業(yè)務(wù)邏輯層(BLL)、界面表示層(UI)三部分,三層架構(gòu)的好處是根據(jù)系統(tǒng)中代碼所處的層次將系統(tǒng)拆開,而通過業(yè)務(wù)模型(Model)再進(jìn)行連接,降低系統(tǒng)各層次之間的耦合度,提升程序開發(fā)和后期維護(hù)的容易度。

三層架構(gòu)是企業(yè)信息管理系統(tǒng)中一種比較流行的架構(gòu)方式,如大家所知,三層架構(gòu)將信息系統(tǒng)分為數(shù)據(jù)訪問層(DAL)、業(yè)務(wù)邏輯層(BLL)、界面表示層(UI)三部分,三層架構(gòu)的好處是根據(jù)系統(tǒng)中代碼所處的層次將系統(tǒng)拆開,而通過業(yè)務(wù)模型(Model)再進(jìn)行連接,降低系統(tǒng)各層次之間的耦合度,提升程序開發(fā)和后期維護(hù)的容易度。

由 于三層架構(gòu)是根據(jù)由上至下的層次進(jìn)行分層,而不是根據(jù)功能、應(yīng)用領(lǐng)域進(jìn)行分層,所以三層架構(gòu)在每一層的關(guān)注點(diǎn)并不相同,數(shù)據(jù)訪問層關(guān)注的是跟數(shù)據(jù)庫(kù)打交道 的部分,業(yè)務(wù)邏輯層關(guān)注的是業(yè)務(wù)邏輯處理部分,而界面表示層關(guān)注的是人機(jī)交互部分,所以三層架構(gòu)在一定程度上也體現(xiàn)出了系統(tǒng)開發(fā)的先后順序和分工。

本文將從我對(duì)三層架構(gòu)的理解上,利用General框架從頭開始打造一個(gè)信息管理系統(tǒng)的初步結(jié)構(gòu),以此來展示General框架在信息管理系統(tǒng)開發(fā)上的優(yōu)勢(shì)。由于不同的人對(duì)架構(gòu)的理解也不一樣,所以本文不強(qiáng)調(diào)架構(gòu)的正確性,只是出于簡(jiǎn)化開發(fā)、方便編程的原則下提供一個(gè)三層架構(gòu)的樣本。本文中的示例工程為一個(gè)小型的商品庫(kù)存管理軟件,源代碼請(qǐng)查看General框架中的Sample.Market工程。

第一步、設(shè)計(jì)業(yè)務(wù)模型

由 于是示例工程,所以本文繞過需求分析過程,直接從業(yè)務(wù)模型設(shè)計(jì)開始。關(guān)于為何從業(yè)務(wù)模型開始,其實(shí)目前主要有兩種開發(fā)順序,即業(yè)務(wù)驅(qū)動(dòng)設(shè)計(jì)和界面驅(qū)動(dòng)設(shè) 計(jì),業(yè)務(wù)驅(qū)動(dòng)設(shè)計(jì)更強(qiáng)調(diào)業(yè)務(wù)作為系統(tǒng)的核心,所有編程工作都圍繞業(yè)務(wù)設(shè)計(jì)展開,而界面驅(qū)動(dòng)設(shè)計(jì)認(rèn)為界面是客戶、項(xiàng)目經(jīng)理、設(shè)計(jì)師、程序員最好的溝通工具, 所以一切以界面為首要確定目標(biāo)。而我認(rèn)為這兩種方式至于哪種更好,需要看實(shí)際情況,假如項(xiàng)目不是很大,而界面又容易確定或是客戶比較注重界面設(shè)計(jì),那界面 驅(qū)動(dòng)設(shè)計(jì)當(dāng)然為優(yōu)選方案,可以先從界面入手,做出DEMO,等客戶滿意后再做業(yè)務(wù)流程的開發(fā)。反之,如果業(yè)務(wù)邏輯更為重要,當(dāng)然是以業(yè)務(wù)驅(qū)動(dòng)設(shè)計(jì)為優(yōu)選方案,而信息管理系統(tǒng)的開發(fā),大部分還是以業(yè)務(wù)為中心,所以除去需求分析之后的第一步也就以業(yè)務(wù)模型設(shè)計(jì)為先。

業(yè)務(wù)模型設(shè)計(jì)可以借助Excel、PowerDesinger等工具,先用Excel整理好業(yè)務(wù)模型比較核心的數(shù)據(jù)信息,然后通過PowerDesinger做出業(yè)務(wù)模型圖(即ER圖),再生成物理數(shù)據(jù)庫(kù)模型,再生成數(shù)據(jù)庫(kù)。本文的業(yè)務(wù)模型圖設(shè)計(jì)如下,并生成了對(duì)應(yīng)各種數(shù)據(jù)庫(kù)的物理數(shù)據(jù)庫(kù)模型,再生成了數(shù)據(jù)庫(kù)的建庫(kù)腳本,Acess通過腳本創(chuàng)建數(shù)據(jù)庫(kù)需要一定的小技巧,這個(gè)方法可以在百度中查到。

我通過PowerDesinger生成的建庫(kù)腳本,分別創(chuàng)建了Access、Sqlite、SqlServer2000、SqlServer2005、Oracle、MySql的數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)名稱都為Market。

#p#

第二步、生成實(shí)體模型

數(shù)據(jù)庫(kù)創(chuàng)建完成后,先用VisualStudio創(chuàng)建名為Sample.Market的解決方案,并創(chuàng)建Sample.Market.Logic(業(yè)務(wù)邏輯層)、Sample.Market.Model(實(shí)體模型庫(kù))、Sample.Market.WinForm(WinForm界面表示層),大家發(fā)現(xiàn)為什么沒有創(chuàng)建數(shù)據(jù)訪問層呢,因?yàn)槲沂抢肎eneral框架進(jìn)行開發(fā),而General框架支持多數(shù)據(jù)庫(kù)并且有ORM功能,所以數(shù)據(jù)訪問層就顯得不是必須的了,也可以將General.Data理解為通用的數(shù)據(jù)訪問層。但是從系統(tǒng)解耦和更針對(duì)性的多數(shù)據(jù)庫(kù)支持出發(fā),再增加一個(gè)系統(tǒng)內(nèi)的數(shù)據(jù)訪問層也有好處,但會(huì)帶來更多的編碼和更多的后期維護(hù)成本,其中利弊需要自己權(quán)衡。

工程創(chuàng)建完畢后,利用General代 碼生成器這個(gè)利器,我們就可以很快的一次性把實(shí)體模型生成出來,注意這個(gè)實(shí)體模型是從數(shù)據(jù)庫(kù)生成而來的,而實(shí)際上實(shí)體模型應(yīng)從業(yè)務(wù)模型而來,因?yàn)閿?shù)據(jù)庫(kù)是 業(yè)務(wù)模型生成而來,而實(shí)體模型又是從數(shù)據(jù)庫(kù)生成而來,所以這三者就成了完全一致的,這樣在開發(fā)角度其實(shí)更方便實(shí)用,因?yàn)橹灰私馄渲幸徽呔涂梢詫?duì)三者完全 了解。但問題是如果業(yè)務(wù)模型發(fā)生變化怎么辦,這個(gè)問題也困擾我很久,因?yàn)殡m然有先進(jìn)的工具做支持,而從業(yè)務(wù)模型生成物理數(shù)據(jù)模型,再修改數(shù)據(jù)庫(kù)結(jié)構(gòu),再?gòu)?數(shù)據(jù)庫(kù)生成實(shí)體類,依然是非常累人的一件事,直到目前我也沒有特別好的辦法解決這個(gè)問題,甚至曾想過制作一個(gè)從設(shè)計(jì)業(yè)務(wù)模型到生成數(shù)據(jù)庫(kù)再到生成實(shí)體類的 完整解決方案工具,但奈何工作量太大是我難以完成的,在此只能提出以下幾點(diǎn)供大家參考:

1)盡量減少業(yè)務(wù)模型的修改,前期設(shè)計(jì)要盡量完善,留足冗余字段,并告知負(fù)責(zé)業(yè)務(wù)調(diào)研同事修改的成本,修改盡量要求客戶簽字確認(rèn);

2)將數(shù)據(jù)庫(kù)和測(cè)試數(shù)據(jù)分開,比如通過SQL腳本錄入測(cè)試數(shù)據(jù),免得修改數(shù)據(jù)庫(kù)結(jié)構(gòu)造成測(cè)試數(shù)據(jù)丟失;

3)工具不是人,沒有人的智能,如果對(duì)數(shù)據(jù)庫(kù)結(jié)構(gòu)或?qū)嶓w類的某個(gè)地方修改了,而重新建庫(kù)或是重新生成實(shí)體類后又忘記復(fù)原,容易導(dǎo)致莫名其妙的BUG,所以盡量避免重新建庫(kù)或一次重新生成所有的實(shí)體類,而是小范圍修改;

4)如果實(shí)在改動(dòng)太多,就拋棄業(yè)務(wù)模型,直接去數(shù)據(jù)庫(kù)修改吧,這樣減少了一大部分工作量,可以避免積勞成疾。

General代碼生成器的使用可以參考?jí)嚎s包內(nèi)的說明教程,生成實(shí)體的模板已經(jīng)包含在模板庫(kù)中,動(dòng)手能力強(qiáng)的可以自己修改或制作符合自己習(xí)慣的模板。

 

#p#

第三步、創(chuàng)建界面表示層

制 作軟件界面其實(shí)是一項(xiàng)非常累人的工作,大概占了整個(gè)系統(tǒng)開發(fā)的一半強(qiáng)的時(shí)間,但是在界面開發(fā)上也有很多竅門,比如通過配置動(dòng)態(tài)生成菜單、通過配置動(dòng)態(tài)生成 表格列、表單自動(dòng)生成自動(dòng)收集填充、下拉框自動(dòng)生成、搜索項(xiàng)自動(dòng)生成并自動(dòng)生成查詢語(yǔ)句、呈現(xiàn)器自動(dòng)綁定字典等等,可以說是只有想不到?jīng)]有做不到,通過這 些技巧可以大大提高開發(fā)的效率,減少很多重復(fù)工作,在以后我會(huì)慢慢介紹這些技巧,本文中將介紹一個(gè)表單自動(dòng)收集填充的技巧。

在General.WinForm.FormHelper和General.Web.WebHelper中都有一個(gè)名為CollectAndFill的方法,分別對(duì)應(yīng)窗體和網(wǎng)頁(yè)的收集和填充,可以對(duì) Object、DataRow、控件集這三者中的任意兩者之間進(jìn)行收集和填充工作,比如對(duì)表單控件收集值并賦值到實(shí)體,對(duì)實(shí)體收集值并賦值給表單,但前提是需要將表單的控件命名為與實(shí)體的屬性相同的名稱以進(jìn)行對(duì)應(yīng)。使用方法如:

創(chuàng)建實(shí)體并收集表單值:

1 Goods good = new Goods();
2 FormHelper.CollectAndFill(this, good);

查詢實(shí)體并賦值給表單

1 Goods good = goodsLogic.GetGoodByCode(編號(hào).Text);
2 FormHelper.CollectAndFill(good, this);

其實(shí)控件的收集填充工作是通過各種控件對(duì)應(yīng)的工具類來完成的,所以如果有收集或填充不到的控件類型,可以通過增加并注冊(cè)新的工具類來實(shí)現(xiàn),具體請(qǐng)參考源代碼。

 

第四步、創(chuàng)建業(yè)務(wù)邏輯層

最重要的業(yè)務(wù)邏輯卻放在最后,因?yàn)楫?dāng)業(yè)務(wù)模型和界面都確定之后,業(yè)務(wù)邏輯其實(shí)也跑不出圈了,只要根據(jù)需要對(duì)應(yīng)完成就行了,可能有人說是不是應(yīng)當(dāng)先創(chuàng)建業(yè)務(wù)邏輯再制作界面,其實(shí)這樣業(yè)務(wù)邏輯的方法反而難以確定,還是以界面制作為優(yōu)先。

General代碼生成器也可以生成業(yè)務(wù)邏輯層的代碼,甚至說界面層的代碼也完全可以生成,如果項(xiàng)目代碼優(yōu)化的比較好,可以通過先生成再修改的辦法來節(jié)約很多時(shí)間,但大部分情況這個(gè)工作重復(fù)度并不高,所以不需要自動(dòng)生成來完成。

創(chuàng)建業(yè)務(wù)邏輯類后,通過DataManager來進(jìn)行數(shù)據(jù)庫(kù)訪問操作,比如下面這個(gè)通過ID獲取商品信息的方法:

  1. /// <summary> 
  2.         /// 通過ID獲取商品信息 
  3.         /// </summary> 
  4.         /// <param name="id">商品ID</param> 
  5.         /// <returns></returns> 
  6.         public Goods GetGoodByID(int id) 
  7.         { 
  8.             return DataManager.Default.Find<Goods>(id); 
  9.         } 

通過一行代碼就可以完成;

再如商品入庫(kù)的方法:

 

  1. /// <summary> 
  2.         /// 商品入庫(kù) 
  3.         /// </summary> 
  4.         /// <param name="good">商品信息</param> 
  5.         /// <param name="stockDate">入庫(kù)日期</param> 
  6.         /// <param name="amount">入庫(kù)數(shù)量</param> 
  7.         /// <returns></returns> 
  8.         public ReturnCode StockInGoods(Goods good, DateTime stockDate, int amount) 
  9.         { 
  10.             Transaction tran = DataManager.Default.BeginTransaction(); 
  11.             try 
  12.             { 
  13.                 // 查詢是否有編號(hào)已存在的商品 
  14.                 Goods tmpGood = DataManager.Default.FindFirst<Goods>("編號(hào) = @bh", good.編號(hào)); 
  15.                 if (tmpGood != null
  16.                 { 
  17.                     good.ID = tmpGood.ID; 
  18.                     good.Attach(); 
  19.                     good.庫(kù)存數(shù)量 = tmpGood.庫(kù)存數(shù)量; 
  20.                     good.庫(kù)存金額 = tmpGood.庫(kù)存金額; 
  21.                     good.進(jìn)貨數(shù)量 = tmpGood.進(jìn)貨數(shù)量; 
  22.                     good.進(jìn)貨金額 = tmpGood.進(jìn)貨金額; 
  23.                 } 
  24.                 else 
  25.                 { 
  26.                     good.Detach(); 
  27.                 } 
  28.  
  29.                 if (good.庫(kù)存數(shù)量 == null) good.庫(kù)存數(shù)量 = 0
  30.                 if (good.庫(kù)存金額 == null) good.庫(kù)存金額 = 0
  31.                 if (good.進(jìn)價(jià) == null) good.進(jìn)價(jià) = 0
  32.                 if (good.進(jìn)貨數(shù)量 == null) good.進(jìn)貨數(shù)量 = 0
  33.                 if (good.進(jìn)貨金額 == null) good.進(jìn)貨金額 = 0
  34.  
  35.                 // 調(diào)整庫(kù)存 
  36.                 good.庫(kù)存數(shù)量 += amount; 
  37.                 good.庫(kù)存金額 += amount * good.進(jìn)價(jià); 
  38.                 good.進(jìn)貨數(shù)量 += amount; 
  39.                 good.進(jìn)貨金額 += amount * good.進(jìn)價(jià); 
  40.                 good.平均進(jìn)價(jià) = good.進(jìn)貨金額 / good.進(jìn)貨數(shù)量; 
  41.                 DataManager.Default.Save(good); 
  42.  
  43.                 // 保存入庫(kù)記錄 
  44.                 GoodsIn goodsIn = new GoodsIn(); 
  45.                 goodsIn.Goo_ID = good.ID; 
  46.                 goodsIn.日期 = stockDate; 
  47.                 goodsIn.編號(hào) = good.編號(hào); 
  48.                 goodsIn.進(jìn)價(jià) = good.進(jìn)價(jià); 
  49.                 goodsIn.零售價(jià) = good.零售價(jià); 
  50.                 goodsIn.數(shù)量 = amount; 
  51.                 goodsIn.金額 = amount * goodsIn.進(jìn)價(jià); 
  52.                 goodsIn.生產(chǎn)日期 = good.生產(chǎn)日期; 
  53.                 goodsIn.保質(zhì)期 = good.保質(zhì)期; 
  54.                 goodsIn.到期日期 = good.到期日期; 
  55.                 goodsIn.生產(chǎn)批號(hào) = good.生產(chǎn)批號(hào); 
  56.                 goodsIn.供應(yīng)商 = good.供應(yīng)商; 
  57.                 DataManager.Default.Save(goodsIn); 
  58.  
  59.                 tran.Commit(); 
  60.                 return ReturnCode.Successed; 
  61.             } 
  62.             catch 
  63.             { 
  64.                 tran.Rollback(); 
  65.                 throw
  66.             } 
  67.         } 

 

即便是對(duì)兩個(gè)表進(jìn)行操作并且使用事務(wù),代碼依舊非常簡(jiǎn)短。

由于各家數(shù)據(jù)庫(kù)的SQL都稍有差別,所以要做到兼容多種數(shù)據(jù)庫(kù)其實(shí)是非常困難的,General框架的數(shù)據(jù)庫(kù)操作是通過拼接SQL語(yǔ)句來完成的,沒有像EntityFramework的Linq或NHibernate的HQL這樣的自身查詢語(yǔ)言,所以要兼容多種數(shù)據(jù)庫(kù)是難以實(shí)現(xiàn)的,而這個(gè)示例程序能夠兼容Access、Sqlite、SqlServer、Oracle、MySql多種數(shù)據(jù)庫(kù),主要是因?yàn)橐韵聨c(diǎn):

1)General框架對(duì)各種數(shù)據(jù)庫(kù)有對(duì)應(yīng)的查詢生成器,同一個(gè)方法對(duì)不同數(shù)據(jù)庫(kù)有不同的SQL生成實(shí)現(xiàn);

2)General框架具有不同參數(shù)前綴替換能力,比如在Oracle中參數(shù)前綴是“:”而不是SqlServer的“@”,General框架會(huì)自動(dòng)將作為通用前綴的“@”替換為Oracle的“:”以便兼容;

3)本示例中沒有使用一些特殊的SQL語(yǔ)句,各家的數(shù)據(jù)庫(kù)在常用的select、insert、update、delete語(yǔ)句上兼容的比較好。

最后,大家可以打開General框架中的示例程序查看具體的使用方法,里面還包含一個(gè)性能測(cè)試程序可以測(cè)試General框架的性能,相關(guān)的源碼下載請(qǐng)參看上一篇文章,歡迎大家評(píng)論。

 
責(zé)任編輯:王雪燕 來源: 博客園
相關(guān)推薦

2013-01-09 11:00:20

架構(gòu)開發(fā)三層架構(gòu).NET架構(gòu)

2012-02-03 09:44:33

.NET

2011-04-19 13:53:41

三層架構(gòu)

2009-05-06 09:40:04

LINQWEB開發(fā)構(gòu)架

2009-08-26 18:20:42

三層架構(gòu)

2019-07-26 08:39:29

JavaWebMVC

2009-07-28 17:25:14

ASP.NET三層結(jié)構(gòu)

2011-08-08 14:14:03

架構(gòu)

2012-04-16 10:45:17

三層架構(gòu)

2009-04-30 15:56:50

三層架構(gòu)MVCMVP

2009-07-28 15:08:50

MVC三層架構(gòu)實(shí)例

2018-10-31 14:32:53

數(shù)據(jù)中心網(wǎng)絡(luò)架構(gòu)

2009-07-02 15:42:46

JSP系統(tǒng)開發(fā)

2018-03-08 15:30:31

超融合架構(gòu)傳統(tǒng)三層架構(gòu)

2009-09-23 17:29:54

三層框架

2013-05-23 10:58:38

三層交換機(jī)vlanvlan通信

2012-02-07 10:40:13

MVCJava

2014-02-12 10:07:07

三層交換原理

2010-03-11 09:56:47

三層交換機(jī)

2012-08-15 11:03:18

框架項(xiàng)目
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久99视频这里只有精品 | 天堂一区| 黄色播放| 另类一区 | 成年网站在线观看 | 日本成人毛片 | 日韩av成人 | 1204国产成人精品视频 | 国产一区二区自拍 | 亚洲高清电影 | 夜久久| 亚洲成人av在线播放 | 欧美日韩在线观看视频网站 | 欧美成人在线影院 | 日韩精品一区二区三区免费视频 | 91精品国产综合久久久久蜜臀 | 人人做人人澡人人爽欧美 | 国产亚洲网站 | 日本精品在线播放 | 欧美高清视频 | 日韩免费在线视频 | 久久久久久免费观看 | 久久青青 | 91精品国产综合久久婷婷香蕉 | 日韩国产在线 | 91免费福利在线 | 欧美日韩成人一区二区 | 欧美国产亚洲一区二区 | 欧美视频一级 | 一区二区三区亚洲 | 久久精品黄色 | 亚洲精品欧美一区二区三区 | 中文字幕在线第一页 | 精品在线一区 | 麻豆久久久久 | 视频羞羞 | 2018国产大陆天天弄 | 亚洲精品久久嫩草网站秘色 | 国产精品久久精品 | 国产一区二区在线免费视频 | 久久久久久久久久久爱 |