日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

三層開發(fā)中容易犯的幾個(gè)錯(cuò)誤

系統(tǒng) 2463 0
前記:

相信大家對(duì)三層開發(fā)都已經(jīng)耳熟能詳,可是我卻發(fā)現(xiàn)新公司的既有代碼中有一些違背分層開發(fā)思想的東西,現(xiàn)在與大家分享這些錯(cuò)誤,我們共勉之。

如果有人覺(jué)得對(duì)三層開發(fā)拿捏得不是太準(zhǔn),請(qǐng)參照李天平的文章: 分層開發(fā)思想與小籠包 , 這篇文章用隱喻說(shuō)明分層開發(fā),是非常好的一篇文章。

正文:

1. 界面層參與非界面邏輯,搶業(yè)務(wù)邏輯層的飯碗

什么是界面邏輯:

界面層應(yīng)該有的邏輯就是顯示的邏輯,例如根據(jù)邏輯結(jié)果顯示某一個(gè) Panel 不顯示另外一個(gè) Panel ,或者有一個(gè)數(shù)據(jù)集應(yīng)該在界面上怎么呈現(xiàn),這是界面層的邏輯

例子場(chǎng)景:

用戶登錄時(shí)首先驗(yàn)證用戶輸入的用戶名是否有效,如果用戶名有效,然后再驗(yàn)證用戶輸入的密碼是否和用戶名匹配,如果匹配則表示用戶可以登錄,增加用戶的登錄次數(shù),然后將用戶的信息寫入 Session 中;否則返回錯(cuò)誤。在這個(gè)過(guò)程中除了將用戶信息寫入 Session 這一步屬于界面邏輯以外其他的操作都應(yīng)該放在業(yè)務(wù)邏輯層。

錯(cuò)誤代碼示例:

private void buttonLogin_Click( object sender,EventArgsev)
{
string userName = textBoxUserName.Text;
string password = textPassword.Text;

if ( Business.Account.Exists (userName))
{
bool success = Business.Account.Login (userName,password);
if (success)
{
Business.Account.AddLoginTime (userName);

Session[
" user " ] = new User(userName,password);
Redirect(
" / " );
}

else
{
this .labelMessage.Text = " 登錄失敗。 " ;
}

}

else
{
this .lableMessage.Text = " 用戶名不存在。 " ;
}

}

分析:在上面的代碼中一個(gè) UI 層的一個(gè)事件中調(diào)用了三次 rules 層的方法:

Business.Account.Exists(userName)

Business.Account.Login(userName, password)

Business.Account.AddLoginTime(userName);

還附加有條件判斷,這種方法在執(zhí)行效果上面是沒(méi)有什么錯(cuò)誤的,可是卻造成了邏輯前移;本來(lái)應(yīng)該在邏輯層執(zhí)行的判斷放在了界面層,是不合適的。

2. 數(shù)據(jù)訪問(wèn)層參與了大量的業(yè)務(wù)邏輯

這種現(xiàn)象經(jīng)常出現(xiàn)在大量使用存儲(chǔ)過(guò)程的系統(tǒng)中,將一大堆邏輯統(tǒng)統(tǒng)放在一個(gè)存儲(chǔ)過(guò)程中實(shí)現(xiàn)了,乍一看可能很有效率,其實(shí)造成了系統(tǒng)結(jié)構(gòu)的失調(diào),給維護(hù)帶來(lái)困難,數(shù)據(jù)訪問(wèn)層甚者數(shù)據(jù)庫(kù)要搶邏輯層的飯碗了。

還以用戶登錄為例:

下面是業(yè)務(wù)邏輯層的登錄方法:

// 業(yè)務(wù)邏輯層的登錄方法
public int Login( string userName, string password)
{
return DataAccess.UserAccount.Login(userName,password);
}


下面是數(shù)據(jù)層的登錄方法:

// 數(shù)據(jù)訪問(wèn)層的登錄方法
public int Login( string userName, string password)
{
SqlParameter[]parameters
= new SqlParameter[] {
//
}
;
return SqlHelper.ExecuteProcedure( " Login " ,parameters);
}


下面是登錄的存儲(chǔ)過(guò)程:

CREATE PROC Login
@userName varchar ( 20 ),
@password varchar ( 20 )
AS
IF NOT EXISTS ( SELECT * FROM UserAccount WHERE UserName = @userName )
RETURN - 1
IF NOT EXISTS ( SELECT * FROM UserAccount WHERE UserName = @userName AND password = @password )
RETURN 1

UPDATE UserAccount
SET LoginTimes = LoginTimes + 1
WHERE UserName = @userName

RETURN 0


分析:從上面三段代碼中我們可以很顯然得看到登錄的業(yè)務(wù)邏輯已經(jīng)全部被后移到了數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程中。這樣使用的三層結(jié)構(gòu)就失去了意義,邏輯層名存實(shí)亡了;而數(shù)據(jù)庫(kù)的壓力會(huì)越來(lái)越大;我們修改業(yè)務(wù)邏輯的時(shí)候不是到邏輯層修改,而是要到數(shù)據(jù)庫(kù)中去修改了。

3. 將界面層上的數(shù)據(jù)組件(如 SqlDataSource )作為參數(shù)傳遞到業(yè)務(wù)邏輯層去賦值

這樣做的壞處很明顯,本來(lái)是界面層依賴于業(yè)務(wù)邏輯層的,現(xiàn)在業(yè)務(wù)邏輯層反過(guò)來(lái)去依賴界面層的類,需要邏輯層引用 System.Web 命名空間,顯然是錯(cuò)誤的。

4. 為了省事兒,不是直接將參數(shù)傳遞到業(yè)務(wù)邏輯層,而是通過(guò) HttpContext 直接獲得界面層應(yīng)該傳遞的參數(shù)

例子:在系統(tǒng)設(shè)計(jì)的初期沒(méi)有記錄用戶登錄的 IP 地址,而到了后期發(fā)現(xiàn)了這個(gè)問(wèn)題,要求紀(jì)錄用戶 IP 了,為了不修改業(yè)務(wù)邏輯層方法的定義,也不用修改界面層的調(diào)用方法,于是便寫出了下面的代碼:

public int Login( string userName, string password)
{
string userIP = System.Web.HttpContext.Current.Request.UserHostAddress;
// followisloginsteps
}

這一點(diǎn)犯的錯(cuò)誤和 3 中的錯(cuò)誤相同,導(dǎo)致層之間形成了依賴環(huán)。

5. 將事務(wù)處理放在數(shù)據(jù)訪問(wèn)層來(lái)做

事務(wù)處理應(yīng)該放在業(yè)務(wù)邏輯層處理,原因是

1 )事務(wù)的劃分是根據(jù)業(yè)務(wù)邏輯來(lái)定義的,通常一個(gè)事務(wù)就代表完成了一個(gè)完整的邏輯操作;

2 )一個(gè)業(yè)務(wù)邏輯可能有幾個(gè)數(shù)據(jù)操作,修改幾個(gè)表中的數(shù)據(jù),而通常數(shù)據(jù)層的類的劃分是根據(jù)數(shù)據(jù)庫(kù)表來(lái)劃分的,如果把事務(wù)處理放在數(shù)據(jù)訪問(wèn)層,那么業(yè)務(wù)層的方法需要調(diào)用兩個(gè)以上的數(shù)據(jù)層方法時(shí),就會(huì)出現(xiàn)執(zhí)行兩個(gè)事務(wù)的情況,顯然這是不合理的。

總結(jié):

1. 在三層結(jié)構(gòu)的劃分中我們應(yīng)該使三層各負(fù)其責(zé),誰(shuí)也不能越權(quán),誰(shuí)也不能懶惰,通常情況下,邏輯層應(yīng)該在滿足各負(fù)其責(zé)的條件下,盡可能的厚。

三層開發(fā)中容易犯的幾個(gè)錯(cuò)誤


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!??!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 眉山市| 博白县| 邢台市| 集安市| 岫岩| 龙海市| 吐鲁番市| 胶南市| 从化市| 湘潭市| 县级市| 武山县| 彰化市| 天全县| 浦城县| 斗六市| 新田县| 诸暨市| 六盘水市| 长沙县| 永清县| 泗水县| 湟中县| 景德镇市| 达拉特旗| 姚安县| 沈阳市| 德州市| 开江县| 类乌齐县| 安溪县| 汪清县| 晋州市| 勃利县| 南汇区| 玉环县| 洮南市| 靖远县| 田林县| 如皋市| 广汉市|