亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

建立三層結構的ASP應用程序

2019-11-18 20:15:25
字體:
來源:轉載
供稿:網友
  本文介紹了三層結構應用程序的概念和優點,并結合一個實例介紹了如何建立三層結構的asp應用程序。


一、兩層結構的ASP應用有何缺點
  在Browser/Server 應用程序開發領域,微軟公司的IIS/ASP以其強大的功能,良好的擴展能力,及與其它微軟產品的一致性,迅速地流行起來。它能使一個具有VB/VC經驗的程序員,很快地成為一個Web程序員,開發出看上去非常專業的應用。但是,ASP有一個天生的缺點,就是ASP代碼和HTML代碼是混在一起的,ASP程序員既需要考慮與數據庫打交道,需要關心如何與HTML配合,有時還需要用ASP直接生成HTML代碼。其結果是,當程序邏輯足夠復雜時,.asp源文件非常長;而且,無論客戶提出用戶界面的改變,還是商業邏輯的改變(比如,在考試系統中,"合格"的標準可能從達到60分就算合格,改為進入前100名才算合格),都需要對.asp文件進行改動,而商業邏輯的改變,很可能需要改動很多文件。


二、三層結構的概念
  在傳統的Client / Server應用中,也存在著上述同樣的問題,多層結構的應用正是在對C/S 結構的總結基礎上產生的,并且也已經擴展到了B/S應用開發領域。 即將應用劃分為三層(可以有更多層,但三層最常見): 用戶界面層,商業邏輯層,數據庫層。 用戶界面層負責處理用戶的輸入和向用戶的輸出,但并不負責解釋其含義(出于效率的考慮,它可能在向上傳輸用戶輸入前進行合法性驗證),這一層通常用前端工具(VB,VC,ASP等)開發;商業邏輯層是上下兩層的紐帶,它建立實際的數據庫連接,根據用戶的請求生成SQL語句檢索或更新數據庫,并把結果返回給客戶端,這一層通常以動態鏈接庫的形式存在并注冊到服務器的注冊簿(Registry)中,它與客戶端通訊的接口符合某一特定的組件標準(如COM,CORBA),可以用任何支持這種標準的工具開發;數據庫層負責實際的數據存儲和檢索。 有了這樣的結構,上面的問題迎刃而解:還是以考試系統中的合格標準為例,在客戶端所有需要顯示合格人員名單的地方,調用這樣一個函數GetQualifiedList,至于這個函數如何編寫,如何與數據庫打交道,以至訪問的是何種數據庫都與其無關(你一定有過這樣的經歷,在一種數據庫系統上運行得很好的SQL語句,有時換到另一種數據庫系統上必須加以修改); 在中間層DLL中實現這個GetQualifiedList函數,如果用戶對"合格"的定義變了,只需要修改這個函數就可以了,只要此函數的入口參數和返回內容不變,在客戶端不需作任何改動。在這里,我們看到了面向對象編程的特性之一封裝性的優點,而這一點在開發大型應用時尤其有用--我們可以把開發人員分成兩組,一組負責開發界面層,另一組負責開發商業邏輯層,雙方只要按照事先商定的函數接口,并行地開發就可以,而不必向從前那樣,后面的工作必須等前面的工作完成后才能開始。當然,這樣的開發模式需要很好的項目協調和文檔作支持。


  你也許會問,如果我把這些函數些在一個單獨的文件中,再在需要調用的地方把它包含進來,不是同樣能達到目的嗎? 第一,這種方法效率不高,無論你把這些函數分散到多少個文件中,當你需要調用其中一個時,總會包含進一些實際上并不需要的函數,這無疑加重了服務器的負擔,對服務器性能要求較高的Web應用尤其如此。 而DLL只在需要時才調入內存且只調入需要的函數,并且多個應用程序實例可以共享同一個DLL實例;第二,設想一個員工,有20個屬性(工號,姓名,年齡,性別......),現在給定某工號,要求返回此員工所有信息。此時如果單純用函數,只能定義20個全局變量,在函數中改變這些變量值,或者定義一個有20個傳參(by reference)參數的函數。顯然,第一種方法很麻煩而一旦增加一個屬性后一種方法就需要更改函數接口。而在一個對象里,既包含成員方法(即函數和過程),也包括成員屬性。如果我們采用對象的方法,則在函數中只需要改變對象的屬性,在函數外可以直接引用改變了的對象屬性值。 這種方法有些類似第一種方法,但1.屬性值無需在函數外逐一說明;2.這些屬性值只屬于對象,與對象無關的代碼不會無意地改變屬性值;3.一旦對象被釋放,這些值會被一起釋放。


三、如何開發三層結構的ASP應用程序
  ASP具有良好的擴充性,我們訪問數據庫時,采用的時ADO對象,訪問文件時,采用的是文件系統對象(fso),其實這時程序已經是三層結構的應用程序了,只不過由于是利用內置的對象而為意識到罷了。這些對象都遵循COM/ActiveX接口,因此我們自己開發的對象也要遵循這個接口。下面,我們就以上文提到的"合格"標準為例,演示如何創建自己的三層結構的ASP應用。


  1。在數據庫系統中建立如下數據庫表:


    Employee: EMPLID char (5) not null,
          Name  char (10) not null,
          Gender char (1) not null,
          Score   int not null
  此表存儲員工信息和考試成績,為簡單起見,這里只包含工號,姓名和性別三項,并且只有一門考試,EMPLID為主鍵。


  2。建立動態鏈接庫
  啟動VB(這里以VB為例,你可以用你喜歡的任何支持ActiveX接口的開發工具開發),新建一工程,工程類型為ActiveX DLL。在工程中新建一個類,取名為Employee。你可以Class Builder可視化的向類中填加屬性和方法,也可以直接手工編輯。首先填加EMPLID屬性如下:
  PRivate msEMPLID as string
  Property Let EMPLID(sEMPLID as string)
   msEMPLID=sEMPLID
  End Property
  Property Get EMPLID() as string
   EMPLID=msEMPLID
  End Property


  一般地講,每一個屬性都應該有Property Let和Property Get兩個方法,它們分別當向屬性賦值和讀取屬性值時被調用。如果某個屬性只被賦值而從不被讀取(這種情況多發生在對應數據庫表的主鍵的屬性上),則Property Get方法可以省略。Property Let方法不能省略。你可以仿照上面的程序再建立Name,Gender和Score三個屬性。然后創建如下方法:


  Public Sub Create(EMPLID as string)
  dim conn as new Connection
  dim rs as new Recordset
  dim sql as string
  "Suppose that you create a DSN in the control panel, the connectionstring property
  "can also be dsn-less string
  conn.ConnectionString="dsn=dsnname;uid=username;passWord=pwd"
  conn.open
  sql="select * from Employee where EMPLID="" & EMPLID & """
  with rs
   .open sql,conn,1,3
   if .eof and .bof then
     exit sub
   else
     msEMPLID=trim(.Fields("EMPLID"))
     msName=trim(.Fields("Name"))
     msGender=trim(.Fields("Gender"))
     msScore=.Fields("Score")
   end if
   .close
  end with
  set rs=nothing
  conn.close
  set conn=nothing
  End Sub
  這里根據EMPLID創建Employee對象,注意數據庫中的值是賦給三個私有變量,而不是直接賦值給屬性,如果你單步調試就會發現,給msEMPLID賦值會調用Property Let EMPLID,也就是給屬性賦值。
  下面我們再創建一個類Employees,并填加如下方法:
  private colQualifiedList as new Collection
  private mnCurrentIndex as integer
  Public Sub GetQualifiedList()
  dim conn as new Connection
  dim rs as new Recordset
  dim sql as string
  "Suppose that you create a DSN in the control panel, the connectionstring property
  "can also be dsn-less string
  conn.ConnectionString="dsn=dsnname;uid=username;password=pwd"
  conn.open
  sql="select EMPLID from Employee where Score>=60 order by Score desc"
  with rs
   .open sql,conn,1,3
   if .eof and .bof then
     exit sub
   else
     do while not .eof
       dim oEmployee as new Employee
       oEmployee.Create trim(.Fields("EMPLID"))
       colQualifiedList.Add oEmployee
       set oEmployee=nothing
     loop
   end if
   .close
  end with
  set rs=nothing
  conn.close
  set conn=nothing
  End Sub
  首先請注意VB中創建類實例的語法dim oEmployee as new Employee,后面會看到,在ASP中創建類實例的語法是不同的。這個方法檢索成績大于等于60的員工工號,并據此創建一個Employee對象,再將此對象加入私有的集合對象中。下面兩個函數遍歷集合中的元素:
  Public Function GetFirst() as Employee
   if colQualifiedList.count>0 then
     mnCurrentIndex=1
     set GetFirst=colQualifiedList.Item(1)
   else
     set GetFirst=nothing
   end if
  End Function
  Public Function GetNext() as Employee
   mnCurrentIndex=mnCurrentIndex+1
   if mnCurrentIndex>colQualifiedList.count then
     set GetNext=nothing
   else
     set GetNext=colQualifiedList.Item(mnCurrentIndex)
   End if
  End Function
  也許你會說,為何不把集合聲明Public,這樣在ASP中不是可以直接引用嗎?確實,這樣也行得通,編程實現起來也更簡單些,但是,這樣做破壞了封裝性原則。因為數據以何格式存儲完全是商業邏輯層的事,與用戶界面層無關,假設有一天你因為每種原因放棄了用集合來存儲數據的設計,而改用數組或記錄集(Recordset)來存儲,那你只需要修改GetFirst和GetNext兩個函數,用戶界面層完全無需修改。
  至此類文件創建完畢,將工程文件存為 test.vbp,選File菜單下的Make test.dll選項將其編譯。
  3.注冊動態鏈接庫
  啟動Web Server 上的Microsoft Transaction Server (Start--Windows NT Optionpack4--Internet Information Server--Internet Service Manager),展開Microsoft Transaction Server--Computer--My Computer--Package Installed,點鼠標右鍵選New--Package--Create Empty Package,輸入包名Test(這里Test是任選的名字,不一定要與DLL同名),OK-Interactive User-the current Logon user--Finish。雙擊Test--Component,右鍵選Component-New-Component-Install New component(s)-- Add File,選擇你剛編譯好的DLL文件,MTS會發現DLL中有兩個類Employee和Employees。至此DLL注冊完畢。


  4.編寫ASP程序
  <HTML><Body>
  <p>Qualified Employee List</p>
  <table border=1 cellspacing=0 cellpadding=0>
  <tr>
   <td>Employee ID</td>
   <td>Name</td>
   <td>Gender</td>
   <td>Score</td>
  </tr>
  <%
   set oEmployees=server.createobject("Test.Employees")
   oEmployees.GetQualifiedList
   set oEmployee=oEmployees.GetFirst()
   do while not oEmployee is nothing
  %>
  <tr>
   <td><%=oEmployee.EMPLID%></td>
   <td><%=oEmployee.Name%></td>
   <td><%=oEmployee.Gender%></td>
   <td><%=oEmployee.Score%></td>
  </tr>
  <%
     set oEmployee=oEmployees.GetNext()
   loop
  %>
  </table>
  </body></html>
  注意在ASP中創建類實例的語法set oEmployees=server.createobject("Test.Employees"),其中Test是DLL的名字,Employees是類的名字; 當然,如果一個函數的返回值是一個對象,類似set oEmployee=oEmployees.GetFirst()這樣的語法也是可以的。
  至此,一個完整的三層結構的應用程序已經完成了,讓我們看以下,如果把"合格"的定義改為:只有成績進入前100名才算合格,程序需要做那些修改。事實上,如果你的數據庫系統是SQL Server,你只需把SQL語句改為:
  sql="select top 100 EMPLID from Employee order by Score desc" 就已經可以了,即使為了跨數據庫系統的兼容性,我們也只需要對GetQualifiedList做如下修改:


  ......
  sql="select EMPLID from Employee order by Score desc"
  with rs
   .open sql,conn,1,3
   if .eof and .bof then
     exit sub
   else
     i=1
     do while (not .eof) and (i<=100)
       dim oEmployee as new Employee
       oEmployee.Create trim(.Fields("EMPLID"))
       colQualifiedList.Add oEmployee
       set oEmployee=nothing
       i=i+1
     loop
   end if
   .close
  end with
  ...


  然后把DLL重新編譯,注冊就可以了,ASP程序完全不必修改。


四.一些說明和注意事項
  1. 由于這個例子比較簡單,在Employee類中可以沒有Create方法,而在Employees類中將員工的所有信息(工號,姓名,性別,成績)都讀出來并將其賦給Employee對象對應的屬性。但在實際應用中,當Employee對象的屬性增多,或表的數量增多,表之間關系變復雜時,還是本文所示的方法更有效,代碼重用的機會更大。


  2. 當DLL被修改后,在MTS中只能將其刪除后重新注冊,因為每次重新編譯后在注冊表中對象的ID值都將重新生成。


  3. 從ASP中調用帶參數的類方法和函數時,所有的變量參數一定要用相應的類型轉換函數轉換后再傳入,否則會引起類型不匹配錯誤,因為VBScript中只有Variant類型,它不能自動轉換成其它類型。例如,有如下的函數定義:


  Public Function Fun1(p1 as string,p2 as integer) as integer
  End Function
  在ASP程序中應如下調用:
  <%
   p1=obj.property1 " Property1 is a string property
   p2=obj.property2 "Property2 is an integer property
   a=obj.Fun1(cstr(p1),cint(p2))
   a=obj.Fun1("aaa",10) " constant parameter need not be changed
  %>


  而下面的兩種寫法是錯誤的:


  <%
   p1=obj.property1 " Property1 is a string property
   p2=obj.property2 "Property2 is an integer property
   a=obj.Fun1(p1,p2) " incorrect,p1 and p2 are variant variables
   p1=cstr(p1)
   p2=cint(p2)
   a=obj.Fun1(p1,p2) " still incorrect
  %>
  這里第二種寫法仍然是錯誤的,即使經過了類型轉換,p1和p2仍然是Variant變量。在VBScript中,數據類型和類型轉換函數只在表達式運算中起作用,變量只有Variant一種類型。


結束語
  以上對多層結構的理論和實踐進行了一番探討,希望能對您的開發有所幫助。這里還有一個問題,即類和類的成員該如何設計。這既涉及面向對象編程的理論,也需要一定的實踐經驗。請參考相關的OOP理論書籍并在實踐中不斷總結,相信您一定能設計出自己的完美的多層結構的應用程序。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲午夜av电影| 日韩福利伦理影院免费| 538国产精品一区二区免费视频| 亚洲欧美色图片| 久久久免费精品视频| 久久久久亚洲精品成人网小说| 日韩一级黄色av| 久久久久这里只有精品| 一区二区三区美女xx视频| 日韩影视在线观看| 欧美日在线观看| 中文字幕精品视频| 国产精品视频公开费视频| 国产精品久久久久久久久久东京| 久久国产精品久久国产精品| 国产精品三级网站| 国产精品中文字幕久久久| 久久这里有精品视频| 午夜精品久久久99热福利| 亚洲成人黄色在线| 亚洲品质视频自拍网| 欧美劲爆第一页| 久久国产精品久久国产精品| 日韩中文第一页| 国产精品com| 亚洲人成亚洲人成在线观看| 韩国v欧美v日本v亚洲| 亚洲免费视频在线观看| 国模吧一区二区三区| 色yeye香蕉凹凸一区二区av| 日韩激情av在线免费观看| 91性高湖久久久久久久久_久久99| 4438全国成人免费| 亚洲精品视频网上网址在线观看| 久久夜色精品国产亚洲aⅴ| 欧美一区深夜视频| 欧美激情亚洲自拍| 黑人巨大精品欧美一区免费视频| www.日本久久久久com.| 欧美在线亚洲一区| 欧美激情网站在线观看| 亚洲欧洲日产国产网站| 91色p视频在线| 欧美激情在线视频二区| 亚洲成人av资源网| 国产精品pans私拍| 最好看的2019的中文字幕视频| 亚洲精品国精品久久99热| 国产在线观看精品| 久久久久久久网站| 久久国产精品免费视频| 久久久久久久久国产| 欧美激情视频免费观看| 亚洲一区二区三区视频| 一区二区三区高清国产| 亚洲午夜女主播在线直播| 日韩欧美在线视频免费观看| 国产成人精品久久亚洲高清不卡| 91美女片黄在线观| 欧美综合激情网| 国产精品美女www爽爽爽视频| 538国产精品一区二区在线| 久久免费视频这里只有精品| 国产精品18久久久久久首页狼| 欧美性生交xxxxxdddd| 国产成人97精品免费看片| 国产精品成人免费电影| 久久影视三级福利片| 欧美日韩亚洲高清| 国产精品久久久久久久久久久新郎| 亚洲国产日韩欧美在线动漫| 亚洲精品www| 国内精品视频在线| 国产亚洲欧美另类中文| 尤物99国产成人精品视频| 国产丝袜一区二区三区免费视频| 国产精品高精视频免费| 91超碰caoporn97人人| 国产午夜精品久久久| 久热精品视频在线观看| 亚洲欧洲免费视频| 久久久久久国产精品三级玉女聊斋| 亚洲性视频网站| 国产精品电影久久久久电影网| 亚洲影视九九影院在线观看| 欧美另类精品xxxx孕妇| 精品久久久久久国产91| 一区二区三区四区视频| 亚洲偷欧美偷国内偷| 欧美大秀在线观看| 色999日韩欧美国产| 国产欧美日韩免费看aⅴ视频| 另类色图亚洲色图| 欧美激情一区二区三区在线视频观看| 亚洲精品一区二区久| 另类色图亚洲色图| 午夜精品视频网站| 国产精品女人久久久久久| 亚洲成人精品视频在线观看| 一区二区中文字幕| 亚洲色图18p| 欧美色欧美亚洲高清在线视频| 亚洲色图av在线| 欧美亚洲国产视频| 日韩欧美在线网址| 日本一区二区三区四区视频| 欧美壮男野外gaytube| 日韩女优在线播放| 91久久久久久久久久久久久| 欧美老少做受xxxx高潮| 国产做受69高潮| 日韩欧美在线免费观看| 中文字幕日韩专区| 黄色成人av在线| 日本精品va在线观看| 日韩欧美在线观看| 国产精品一区二区久久久久| 日韩免费在线观看视频| 久久亚洲一区二区三区四区五区高| 欧美大片免费观看在线观看网站推荐| 亚洲电影免费观看高清| 亚洲激情在线观看| 日韩av快播网址| 欧美日本高清一区| 国产精品黄页免费高清在线观看| 久久影院在线观看| 日韩在线观看免费高清完整版| 51ⅴ精品国产91久久久久久| 欧美激情a∨在线视频播放| 欧美乱大交做爰xxxⅹ性3| 欧美日韩国产成人在线观看| 欧美性猛交xxxx免费看| 日韩最新免费不卡| 亚洲free嫩bbb| 精品av在线播放| 日韩av电影在线免费播放| 亚洲成在人线av| 日韩av在线导航| 亚洲理论电影网| 97成人精品视频在线观看| 不卡伊人av在线播放| 日韩www在线| 久久久精品一区二区三区| 91av福利视频| 亚洲精品美女在线观看播放| 国产在线观看精品一区二区三区| 色偷偷9999www| 欧美综合国产精品久久丁香| www.日韩av.com| 成人激情综合网| 欧美成人午夜影院| 国产a∨精品一区二区三区不卡| 97在线免费观看视频| 国产精品福利在线观看网址| 成人性生交大片免费观看嘿嘿视频| 欧美激情国产高清| 国产自摸综合网| 欧美日韩国产二区| 亚洲第一福利在线观看| 国产美女搞久久| 亚洲aa在线观看| 亚洲精选在线观看| 国产精品国产三级国产专播精品人| 国产人妖伪娘一区91|