免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
對“三層結(jié)構(gòu)”的深入理解——怎樣才算是一個符合“三層結(jié)構(gòu)”的Web應(yīng)用程序? - Java...

“三層結(jié)構(gòu)”是什么?

  “三層結(jié)構(gòu)”一詞中的“三層”是指:“表現(xiàn)層”、“中間業(yè)務(wù)層”、“數(shù)據(jù)訪問層”。其中:

n            表 現(xiàn) 層:位于最外層(最上層),離用戶最近。用于顯示數(shù)據(jù)和接收用戶輸入的數(shù)據(jù),為用戶提供一種交互式操作的界面。

n            中間業(yè)務(wù)層:負(fù)責(zé)處理用戶輸入的信息,或者是將這些信息發(fā)送給數(shù)據(jù)訪問層進(jìn)行保存,或者是調(diào)用數(shù)據(jù)訪問層中的函數(shù)再次讀出這些數(shù)據(jù)。中間業(yè)務(wù)層也可以包括一些對“商業(yè)邏輯”描述代碼在里面。

n            數(shù)據(jù)訪問層:僅實(shí)現(xiàn)對數(shù)據(jù)的保存和讀取操作。數(shù)據(jù)訪問,可以訪問數(shù)據(jù)庫系統(tǒng)、二進(jìn)制文件、文本文檔或是XML文檔。

  

 

  對依賴方向的研究將是本文的重點(diǎn),數(shù)值返回方向基本上是沒有變化的。


在一個

  如果只以分層的設(shè)計角度看,Duwamish7要比PetShop3.0復(fù)雜一些!而如果較為全面的比較二者,PetShop3.0則顯得比較復(fù)雜。但我們先不討論這些,對PetShop3.0Duwamish7的研究,并不是本文的重點(diǎn)?,F(xiàn)在的問題就是:既然“三層結(jié)構(gòu)”已經(jīng)被分派到各自的項目中,那么剩下來的項目是做什么的呢?例如PetShop3.0中的“Model”、“IDAL”、“DALFactory”這三個項目,再例如Duwamish7中的“Common”項目,還有就是在Bincess.CN彬月論壇中的“Classes”、“DbTask”、這兩個項目。它們究竟是做什么用的呢?

 

對“三層結(jié)構(gòu)”的深入理解——從一家小餐館說起

  一個“三層結(jié)構(gòu)”的Web應(yīng)用程序,就好象是一家小餐館。

n            表 現(xiàn) 層,所有的.aspx頁面就好像是這家餐館的菜譜。

n            中間業(yè)務(wù)層,就像是餐館的服務(wù)生。

n            數(shù)據(jù)訪問層,就像是餐館的大廚師傅。

n            而我們這些網(wǎng)站瀏覽者,就是去餐館吃飯的吃客了……

 

 

我們?nèi)ヒ患也宛^吃飯,首先得看他們的菜譜,然后喚來服務(wù)生,告訴他我們想要吃的菜肴。服務(wù)生記下來以后,便會馬上去通知大廚師傅要烹制這些菜。大廚師傅收到通知后,馬上起火燒菜。過了不久,服務(wù)生便把一道一道香噴噴的、熱氣騰騰的美味端到我們的桌位上——

而我們訪問一個基于asp.net技術(shù)的網(wǎng)站的時候,首先打開的是一個aspx頁面。這個aspx頁面的后臺程序會去調(diào)用中間業(yè)務(wù)層的相應(yīng)函數(shù)來獲取結(jié)果。中間業(yè)務(wù)層又會去調(diào)用數(shù)據(jù)訪問層的相應(yīng)函數(shù)來獲取結(jié)果。 

為什么需要“三層結(jié)構(gòu)”?——初探,就從數(shù)據(jù)庫的升遷開始

一個站點(diǎn)中,訪問數(shù)據(jù)庫的程序代碼散落在各個頁面中,就像夜空中的星星一樣繁多。這樣一動百動的維護(hù),難度可想而知。最難以忍受的是,對這種維護(hù)工作的投入,是沒有任何價值的……

有一個比較好的解決辦法,那就是將訪問數(shù)據(jù)庫的代碼全部都放在一個程序文件里。這樣,數(shù)據(jù)庫平臺一旦發(fā)生變化,那么只需要集中修改這一個文件就可以了。我想有點(diǎn)開發(fā)經(jīng)驗的人,都會想到這一步的。這種“以不變應(yīng)萬變”的做法其實(shí)是簡單的“門面模式”的應(yīng)用。如果把一個網(wǎng)站比喻成一家大飯店,那么“門面模式”中的“門面”,就像是飯店的服務(wù)生,而一個網(wǎng)站的瀏覽者,就像是一個來賓。來賓只需要發(fā)送命令給服務(wù)生,然后服務(wù)生就會按照命令辦事。至于服務(wù)生經(jīng)歷了多少辛苦才把事情辦成?那個并不是來賓感興趣的事情,來賓們只要求服務(wù)生盡快把自己交待事情辦完。我們就把ListLWord.aspx.cs程序就看成是一個來賓發(fā)出的命令,而把新加入的LWordTask.cs程序看成是一個飯店服務(wù)生,那么來賓發(fā)出的命令就是:

“給我讀出留言板數(shù)據(jù)庫中的數(shù)據(jù),填充到DataSet數(shù)據(jù)集中并顯示出來!”

而服務(wù)生接到命令后,就會依照執(zhí)行。而PostLWord.aspx.cs程序,讓服務(wù)生做的是:

“把我的留言內(nèi)容寫入到數(shù)據(jù)庫中!”

而服務(wù)生接到命令后,就會依照執(zhí)行。這就是TraceLWord2!可以在CodePackage/TraceLWord2目錄中找到——

 

把所有的有關(guān)數(shù)據(jù)訪問的代碼都放到LWordTask.cs文件里,LWordTask.cs程序文件如下:

 

#001 using System;

#002 using System.Data;

#003 using System.Data.OleDb;   // 需要操作 Access 數(shù)據(jù)庫

#004 using System.Web;

#005

#006 namespace TraceLWord2

#007 {

#008    /// <summary>

#009    /// LWordTask 數(shù)據(jù)庫任務(wù)類

#010    /// </summary>

#011    public class LWordTask

#012    {

#013        // 數(shù)據(jù)庫連接字符串

#014        private const string DB_CONN=@"PROVIDER=Microsoft.Jet.OLEDB.4.0;

DATA Source=C:\DbFs\TraceLWordDb.mdb";

#015

#016        /// <summary>

#017        /// 讀取數(shù)據(jù)庫表 LWord,并填充 DataSet 數(shù)據(jù)集

#018        /// </summary>

#019        /// <param name="ds">填充目標(biāo)數(shù)據(jù)集</param>

#020        /// <param name="tableName">表名稱</param>

#021        /// <returns>記錄行數(shù)</returns>

#022        public int ListLWord(DataSet ds, string tableName)

#023        {

#024            string cmdText="SELECT * FROM [LWord] ORDER BY [LWordID] DESC";

#025

#026            OleDbConnection dbConn=new OleDbConnection(DB_CONN);

#027            OleDbDataAdapter dbAdp=new OleDbDataAdapter(cmdText, dbConn);

#028

#029            int count=dbAdp.Fill(ds, tableName);

#030

#031            return count;

#032        }

#033

#034        /// <summary>

#035        /// 發(fā)送留言信息到數(shù)據(jù)庫

#036        /// </summary>

#037        /// <param name="textContent">留言內(nèi)容</param>

#038        public void PostLWord(string textContent)

#039        {

#040            // 留言內(nèi)容不能為空

#041            if(textContent==null || textContent=="")

#042                throw new Exception("留言內(nèi)容為空");

#043

#044            string cmdText="INSERT INTO [LWord]([TextContent]) VALUES(@TextContent)";

#045

#046            OleDbConnection dbConn=new OleDbConnection(DB_CONN);

#047            OleDbCommand dbCmd=new OleDbCommand(cmdText, dbConn);

#048

#049            // 設(shè)置留言內(nèi)容

#050            dbCmd.Parameters.Add(new OleDbParameter("@TextContent", OleDbType.LongVarWChar));

#051            dbCmd.Parameters["@TextContent"].Value=textContent;

#052

#053            try

#054            {

#055                dbConn.Open();

#056                dbCmd.ExecuteNonQuery();

#057            }

#058            catch

#059            {

#060                throw;

#061            }

#062            finally

#063            {

#064                dbConn.Close();

#065            }

#066        }

#067    }

#068 }

 

如果將數(shù)據(jù)庫從Access 2000修改為SQL Server 2000,那么只需要修改LWordTask.cs這一個文件。如果LWordTask.cs文件太大,也可以把它切割成幾個文件或“類”。如果被切割成的“類”還是很多,也可以把這些訪問數(shù)據(jù)庫的類放到一個新建的“項目”里。當(dāng)然,原來的ListLWord.aspx.cs文件應(yīng)該作以修改,LWord_DataBind函數(shù)被修改成:

 

...

#046        private void LWord_DataBind()

#047        {

#048            DataSet ds=new DataSet();

#049            (new LWordTask()).ListLWord(ds, @"LWordTable");

#050

#051            m_lwordListCtrl.DataSource=ds.Tables[@"LWordTable"].DefaultView;

#052            m_lwordListCtrl.DataBind();

#053        }

...

 

原來的PostLWord.aspx.cs文件也應(yīng)作以修改,Post_ServerClick函數(shù)被修改成:

 

...

#048        private void Post_ServerClick(object sender, EventArgs e)

#049        {

#050            // 獲取留言內(nèi)容

#051            string textContent=this.m_txtContent.Value;

#052

#053            (new LWordTask()).PostLWord(textContent);

#054

#055            // 跳轉(zhuǎn)到留言顯示頁面

#056            Response.Redirect("ListLWord.aspx", true);

#057        }

...

 

  從前面的程序段中可以看出,ListLWord.aspx.csPostLWord.aspx.cs這兩個文件已經(jīng)找不到和數(shù)據(jù)庫相關(guān)的代碼了。只看到一些和LWordTask類有關(guān)系的代碼,這就符合了“設(shè)計模式”中的一種重要原則:“迪米特法則”。“迪米特法則”主要是說:讓一個“類”與盡量少的其它的類發(fā)生關(guān)系。在TraceLWord1中,ListLWord.aspx.cs這個類和OleDbConnectionOleDbDataAdapter都發(fā)生了關(guān)系,所以它破壞了“迪米特法則”。利用一個“中間人”是“迪米特法則”解決問題的辦法,這也是“門面模式”必須遵循的原則。下面就引出這個LWordTask門面類的示意圖:

 

 

ListLWord.aspx.csPostLWord.aspx.cs兩個文件對數(shù)據(jù)庫的訪問,全部委托LWordTask類這個“中間人”來辦理。利用“門面模式”,將頁面類和數(shù)據(jù)庫類進(jìn)行隔離。這樣就作到了頁面類不依賴于數(shù)據(jù)庫的效果。以一段比較簡單的代碼來描述這三個程序的關(guān)系:

 

public class ListLWord

{

private void LWord_DataBind()

{

    (new LWordTask()).ListLWord( ... );

    }

}

 

public class PostLWord

{

    private void Post_ServerClick(object sender, EventArgs e)

    {

        (new LWordTask()).PostLWord( ... );

    }

}

 

public class LWordTask

{

    public DataSet ListLWord(DataSet ds)...

 

    public void PostLWord(string textContent)...

}

 


應(yīng)用中間業(yè)務(wù)層,實(shí)現(xiàn)“三層結(jié)構(gòu)”

前面這種分離數(shù)據(jù)訪問代碼的形式,可以說是一種“三層結(jié)構(gòu)”的簡化形式。因為它沒有“中間業(yè)務(wù)層”也可以稱呼它為“二層結(jié)構(gòu)”。一個真正的“三層”程序,是要有“中間業(yè)務(wù)層”的,而它的作用是連接“外觀層”和“數(shù)據(jù)訪問層”。換句話說:“外觀層”的任務(wù)先委托給“中間業(yè)務(wù)層”來辦理,然后“中間業(yè)務(wù)層”再去委托“數(shù)據(jù)訪問層”來辦理……

那么為什么要應(yīng)用“中間業(yè)務(wù)層”呢?“中間業(yè)務(wù)層”的用途有很多,例如:驗證用戶輸入數(shù)據(jù)、緩存從數(shù)據(jù)庫中讀取的數(shù)據(jù)等等……但是,“中間業(yè)務(wù)層”的實(shí)際目的是將“數(shù)據(jù)訪問層”的最基礎(chǔ)的存儲邏輯組合起來,形成一種業(yè)務(wù)規(guī)則。例如:“在一個購物網(wǎng)站中有這樣的一個規(guī)則:在該網(wǎng)站第一次購物的用戶,系統(tǒng)為其自動注冊”。這樣的業(yè)務(wù)邏輯放在中間層最合適:

 

 

在“數(shù)據(jù)訪問層”中,最好不要出現(xiàn)任何“業(yè)務(wù)邏輯”!也就是說,要保證“數(shù)據(jù)訪問層”的中的函數(shù)功能的原子性!即最小性和不可再分。“數(shù)據(jù)訪問層”只管負(fù)責(zé)存儲或讀取數(shù)據(jù)就可以了。

  在新TraceLWord3中,應(yīng)用了“企業(yè)級模板項目”。把原來的LWordTask.cs,并放置到一個單一的項目里,項目名稱為:AccessTask。解決方案中又新建了一個名稱為:InterService的項目,該項目中包含一個LWordService.cs程序文件,它便是“中間業(yè)務(wù)層”程序。

ASP.NET Web應(yīng)用程序解決方案中,并不是說有aspx文件、有dll文件、還有數(shù)據(jù)庫,就是“三層結(jié)構(gòu)”的Web應(yīng)用程序,這樣的說法是不對的。也并不是說沒有對數(shù)據(jù)庫進(jìn)行操作,就不是“三層結(jié)構(gòu)”的。其實(shí)“三層結(jié)構(gòu)”是功能實(shí)現(xiàn)上的三層。例如,在微軟的ASP.NET示范實(shí)例“Duwamish7中,“表現(xiàn)層”被放置在“Web”項目中,“中間業(yè)務(wù)層”是放置在“BusinessFacade”項目中,“數(shù)據(jù)訪問層”則是放置在“DataAccess”項目中……而在微軟的另一個ASP.NET示范實(shí)例“PetShop3.0中,“表現(xiàn)層”被放置在“Web”項目中,“中間業(yè)務(wù)層”是放置在“BLL”項目中,而“數(shù)據(jù)訪問層”則是放置在“SQLServerDAL”和“OracleDAL”兩個項目中。在Bincess.CN彬月論壇中,“表現(xiàn)層”是被放置在“WebForum”項目中,“中間業(yè)務(wù)(服務(wù))層”是被放置在“InterService”項目中,而“數(shù)據(jù)訪問層”是被放置在“SqlServerTask”項目中。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
層?為什么軟件開發(fā)要分層
web服務(wù)器、應(yīng)用服務(wù)器、數(shù)據(jù)庫服務(wù)器和存儲服務(wù)器的關(guān)系和區(qū)別是什么?
如何理解.Net的三層架構(gòu)--51編程網(wǎng)
三層架構(gòu)
iOS開發(fā)總結(jié)——項目目錄結(jié)構(gòu)
從java中的hibernate看Ado.net 與NHibernate的關(guān)系
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服