| 導購 | 订阅 | 在线投稿
分享
 
 
 

應用程序規劃與設計 [1]

來源:互聯網  2008-06-01 01:10:47  評論

摘要:了解如何規劃和設計 asp.net 應用程序。本文以一個知識庫 Web 應用程序爲例,討論實際應用程序創建實踐中最常見的幾個因素。(本文包含一些指向英文站點的鏈接。)

目錄

簡介

規劃基本 ASP.NET 應用程序

定義應用程序體系結構

安全規劃

完成設計文檔

小結並付諸行動簡介

歡迎來到「進入 ASP.NET 世界」。在隨後的幾周或幾個月中,本系列文章將逐步具體介紹如何使用 Microsoft® ASP.NET 和 Microsoft Visual Studio® .NET 來設計、實現和部署典型的 Web 應用程序,以探討實際應用程序創建實踐中最常見的幾個因素。我們不僅僅布置一些 Web 窗體,也不局限于只對後端數據庫進行一些數據綁定。數據綁定和 Web 窗體布局很重要,但是有許多其他問題也非常重要。

例如,無論采用何種目標平台或語言,所有經過良好編碼的項目都包括一些基本的規劃步驟,例如目標聲明、用戶方案文檔,甚至用于標識解決方案的物理邊界和邏輯邊界的體系結構文檔。此外,在解決方案生命周期的早期就將安全規劃包含在內是一種非常好的習慣。這些內容與良好的數據庫模型、精心設計的中間件組件以及簡潔的用戶界面設計一起,可以確保您最終在生産中部署的應用程序是安全的、可靠的,並且是用戶友好的。

此時,一些讀者可能會認爲本文屬于那些基調很高的文章,目標定位在某些超大型企業級方案,而這種方案根本不適用于一般的小工廠、愛好者或個人開發團體。其實並不是這樣!即使只是創建您自己個人使用的基于 Web 的小型解決方案,從一開始就進行完善的規劃將有助于確保流程最終的輕松實現和部署。而且,並不是高級的程序員或 Web 開發人員才可以使用這些技術。無論您的技術水平如何,也無論您屬于哪類目標讀者,我相信您都會發現這一系列文章對您很有幫助,它爲您提供了豐富的信息,而且(請答應我這樣說)十分有趣。

我們將生成一個稱爲 DotNetKB 的示例知識庫 Web 應用程序,這個過程將貫穿整個系列文章。在作爲第一篇文章的本文中,我們將介紹典型項目的設計階段,包括基本規劃、應用程序體系結構和實現方案設計。學習完本文後,您將已經預備好所有的文檔,並會迫不及待地希望開始創建解決方案。

預備工作非常簡單,我們跳過這部分內容,直接開始第一步「應用程序規劃」。規劃基本 ASP.NET 應用程序

使用 Visual Studio .NET 創建基于 Web 的 ASP.NET 應用程序的第一步是制定基本的應用程序規劃 (AP)。制定規劃不僅對于由多個開發人員建立的大型解決方案而言是必不可少的,而且即使對于最小的應用程序,一個完善的 AP 也是非常重要的。創建 AP 有助于您在開始編碼「之前」就能仔細考慮一些常見問題。這樣,您可以在應用程序生命周期的早期便完全了解挑戰和解決方案,而不是在完全陷入窘境之後才發現問題。在《Software PRoject Survival Guide》一書中,作者 Steve McConnell 指出:在軟件項目後期糾正錯誤所花的成本與在早期階段發現並糾正這些錯誤所花的成本相比,前者可能是後者的 50 - 200 倍。

一個完善的項目規劃包含哪些內容?可以包含許多內容,但最基本的是要包含目標聲明和一系列用戶方案。還有其他很多有用的資料,包括需求文檔、編碼標准、交付進度、測試過程等。對于我們要建立的簡單示例解決方案,將主要介紹簡單的應用程序聲明和一些用戶方案。同時還將解決一些其他問題。

應用程序聲明

此系列文章要建立的項目(稱爲 DotNetKB)是一個簡單的知識庫 Web 站點,在這個站點中,用戶可以提各種問題,並可以得到授權「專家」的回答。這樣,以後訪問者在查找常見 ASP.NET 問題的解決方案時,可以對得到的結果數據進行搜索和過濾。

這是對我們的 DotNetKB 項目的一個基本目標聲明。DotNetKB 是一個基于 Web 的應用程序,它可以列出訪問者提出的一系列問題,並顯示授權專家對這些問題作出的回複。訪問者可以向系統添加新問題,並可以按照問題的主題、問題和/或回答中的要害字來搜索和過濾這些問題。訪問者還可以按主題或按添加到系統中的日期來對問題列表進行排序。

授權專家可以登錄到應用程序中已設置安全機制的部分,審閱問題,添加、編輯和刪除對一個問題的一個或多個回答。應用程序治理員還可以建立專家登錄權限和登錄配置文件,以及添加、編輯和刪除問題主題。

此外,還提供了一些基本統計信息,包括系統中問題和回答的數量,以及每個專家的回複數量和至今已被訪問的頁面數量。

正如您從上面的聲明中看到的那樣,該解決方案非常簡單。在閱讀目標聲明時,您可能會開始考慮可以添加到這個應用程序的許多其他功能,以使應用程序更加強大。這說明了項目目標聲明的一個主要依據,即避免「功能蔓延」。我們都清楚,假如更改最終結果本來基于的概念,簡單的想法將導致非常龐大且歪曲的結果。有句老格言:「假如不知道要去往何方,你可能會在某個地方停下來」,它原本揭示的是夏季公路旅行,其道理同樣可用于軟件項目。

一些項目的目標聲明中可能需要包含更多的信息。而對于我們的使用,上面的目標聲明就符合要求。現在我們對于要完成的應用程序有了一個清楚的熟悉,接下來需要一些具體的信息來描述用戶如何與系統交互以及用戶需要執行哪些任務來完成目標。我們需要一系列用戶方案。

文檔化用戶方案

用戶方案沒有什麽令人驚異之處。通常,它們只是描述用戶如何與應用程序交互。用戶方案的要害價值在于記錄了關于每個人對用戶希望系統如何運行以及應用程序應如何響應的設想。通過完成這個過程,您將可以完全了解處理各種用戶與系統的交互時所需的數據點和函數。換句話說,編寫完善的用戶方案將有助于您確定完成解決方案需要實現的數據庫、中間件和用戶界面元素。

注重:Visual Studio .NET Enterprise Architect 有一項非常不錯的功能,即答應您使用 Microsoft Visio® 通過 UML(統一建模語言)創建用戶方案,然後生成這些方案的基本代碼。在這裏,我不打算深入探討這些細節,但是您可以在 MSDN® Academic Alliance 站點找到一篇關于這一主題的好文章 Generating .NET Code Using Visio Enterprise Architect's UML,作者是 Sreedhar Koganti。

有了上一節的目標聲明後,下面是 DotNetKB 項目的幾個示例用戶方案。

搜索知識庫

匿名用戶可以輸入一個或多個要害字並執行搜索,搜索將返回包含這些要害字的問題和/或回答列表。用戶可以將要害字搜索鎖定在僅搜索問題、僅搜索回答或者二者都搜索。返回的列表將顯示問題及其回複數和被其他用戶訪問的次數。單擊鏈接將返回以時間先後逆序排列的回複(純文本)列表。

將新問題輸入到知識庫中

匿名用戶可以浏覽用于向數據庫輸入新問題以供授權專家審閱和回複的屏幕。用戶可以輸入問題的標題和內容,並可以選擇在一系列主題中的某個主題下記錄該問題。用戶還可以輸入他們的名字和相關的 URL(電子郵件、Web 地址等)。輸入將被驗證,以確保包含必需的數據並確保所有輸入數據不會受到腳本攻擊等。一旦數據經過驗證並被保存到數據庫中,用戶將看到一個響應屏幕,感謝用戶的支持並將用戶直接連接到主頁。此外,用戶還可以選擇讓該站點「記住」他們的姓名和 URL 以備以後訪問該站點時使用。

您已經了解它的工作原理了,對嗎?每一個方案都嘗試細化用戶交互的重要方面。例如,上面列出的兩個方案表明用戶爲「anonymous」(匿名用戶),這表示這類用戶不需要登錄或進行其他方式的授權。第二個示例還標識了若幹輸入值、驗證步驟和可選操作。

當然,這只是兩個示例;完整的系統需要更多的方案。此外,需要非凡注重的是,「用戶」不僅僅可以是人,也可以是您的程序需要與其通信的其他應用程序,甚至還可以是您的應用程序的其他部分。例如,一個方案描述主頁如何列出最近添加到知識庫中的內容,以供任何人查看。此例中的「用戶」將是主頁自身。還有一些方案描述專家如何查找和回複新問題以及治理員如何更新主題列表並治理系統的其他部分。我已爲討論這個簡單的應用程序標識了 20 多種方案。您可以在 DotNetKB 中找到當前列表(以及與此項目相關的所有其他資料)。

至此我們就有了目標聲明和一些用戶方案。現在,是時候稍憩一下,然後學學一些技術了。我們需要定義應用程序體系結構,這可以幫助我們以「鮮活有效的代碼」實際實現方案。定義應用程序體系結構

有了基本的目的和爲解決方案開發的用戶方案列表後,您需要開始籌劃整體的體系結構。主要目標是標識應用程序的邏輯方面和物理方面,即如何將應用程序拆分爲各種有用的部分。在本節中還添加了安全性方面的內容。安全是在規劃的「一開始」您就需要考慮的問題,而不是在開發周期中「最後添加」的內容。我們稍後會在本節中具體討論這個問題。

邏輯體系結構

從邏輯上講,您需要規劃解決方案以標識數據存儲、數據訪問、業務規則、用戶界面等之間的「邊界」。通常,Web 開發人員會選擇一個兩階段模型,並用 Web 窗體存儲用于訪問現有數據存儲系統(例如 Microsoft SQL Server)的所有代碼。一個更有效的方法是創建一個位于 Web 窗體用戶界面與 SQL Server 數據存儲系統之間的中間層組件庫。這種三層方法(Web 窗體、組件、數據庫)通常是大多數應用程序所需的。但是,在某些情況下,可能需要一個其他層來處理服務器之間傳輸的數據。這個傳輸層可以使用獨立于平台的協議(例如 xml-SOAP)來實現。但是,假如您從頭到尾都使用 Microsoft .NET 技術,則可以使用 .NET 遠程協議的二進制版來完成這一任務,而且速度比使用 XML-SOAP 要快得多。

對于我們的示例,我們將定義三個邏輯邊界:用戶界面(Web 窗體)、中間層(一個 .NET 組件程序集)和數據層(SQL Server 數據庫)。圖 1 顯示了如何表示這一內容。

應用程序規劃與設計 [1]

圖 1:三層圖

現在我們有一個簡單的邏輯模型。它是如何起作用的?它有助于我們考慮各個邏輯組之間的邊界。每個邏輯層應盡量與其他層獨立。理想的情況是,圖層中的更改應該對整體産生最小的影響。例如,假如將數據存儲從 SQL Server 更改到 XML 數據文件,唯一受到影響的圖層應是中間層圖層。用戶界面應該根本無需考慮更改。這會使您進行思考:如何實現解決方案的實際編碼以實現此原則。

另外,邏輯層有助于我們考慮安全問題。各個圖層之間的邊界都存在潛在的安全漏洞。而且,各個圖層可能有自己特定的安全措施(SQL Server 權限、.NET 運行時權限、ASP.NET 安全等)。同樣,我們稍後會在本節中具體討論這個問題。

物理體系結構

確定邏輯層後,考慮物理層也很重要。例如,您可以在同時安裝有 SQL Server、Internet Information Server、ASP.NET 和 .NET 運行時的單個實際計算機上實現這個應用程序。這將是一個物理層。但更可靠且可擴展的方法是:在由三個 Web 服務器組成的簇上部署 Web 窗體,在兩個應用服務器上部署 .NET 組件程序集,在兩個故障恢複模式的 SQL Server 上部署數據庫。這樣産生的物理體系結構將七個 Windows 服務器包含在三個主要組中:Web 簇、組件簇和數據庫簇。假如您了解系統的不同邏輯部件可以位于不同的計算機上,您可能會實現不同的代碼。

對于我們的示例,我們采用一個有效且強大的兩層模型:Web 服務器托管用戶界面和組件,數據庫服務器托管 SQL Server 數據存儲。假如通信量非常大,這個模型使我們可以靈活地在簇中添加更多的服務器,並使其保持足夠的簡潔以便于處理。下面的圖像顯示了此物理體系結構與前面定義的邏輯體系結構之間的映射關系。

應用程序規劃與設計 [1]

圖 2:物理體系結構與三層體系結構之間的映射關系

正如您看到的那樣,邏輯體系結構和物理體系結構不必相同。在規劃階段還要考慮一項內容:安全。安全規劃

Microsoft 有一個關于安全性與軟件這一主題的歌訣:「Secure by design, secure by default, and secure by deployment(設計安全,默認安全和部署安全)」。即,在安全中設計,期待系統在默認情況下是安全的,以及創建可以在安全環境中成功部署的解決方案。安全始終是重要的。既然越來越多的軟件要在公用的 Internet 上「生存」,編寫安全的軟件就更加要害。對于我們而言,幸運的是,.NET 運行時和 Windows 操作系統提供廣泛的安全選項和功能,我們可以輕松地將其包含在我們的應用程序中。無需過分注重標識和消除聯機解決方案中安全漏洞的細節,我們可以指出其中一些最常見的漏洞並指出我們的應用程序規劃如何進行處理。

注重:有關可用選項的具體信息,請參閱 Microsoft Security Developer Center。

緩沖區溢出

這可能是已編譯應用程序中最常見的安全漏洞。由于我們將使用 .NET 運行時,而它是設計用來在內存中安全運行的,因此不太可能發生緩沖區溢出。此外,我們使用 Microsoft Visual Basic® .NET 對解決方案進行編碼,而 Microsoft Visual Basic® .NET 不像 C 或 C++ 那樣輕易受到緩沖區溢出問題的影響。但是,即使我們打算用 C++ 創建組件,我們還可以使用編譯程序的非凡功能,GS 轉換,來保護我們免受大多數緩沖區溢出的攻擊。

數據庫攻擊

另一種常見的安全漏洞可能會使惡意用戶獲得訪問存儲在數據庫中的原始數據的權限。爲了防止黑客獲得數據的控制權,我們僅使用 SQL Server 存儲過程,而不使用「內聯查詢」。這樣可以大大減少試圖在輸入流中插入其他 SQL 命令的攻擊。我們還在程序中多個位置處使用輸入驗證,以確保所有輸入僅包含有效的字符。

交叉站點腳本攻擊

對 Web 應用程序進行的常見攻擊還有一種,它涉及到用戶在輸入流中添加客戶方腳本,這類攻擊將執行附加的對話並誘騙用戶將個人數據發送到黑客自己的 Web 站點。要解決這個問題,我們使用 ASP.NET 1.1 的一個新功能,過濾出這種惡意代碼的所有輸入,防止將它置入系統中。顯示屏幕上還包含附加代碼,它將自動禁用任何腳本或顯示可能會插入到數據存儲中的標記。

至此,我們已獲得了應用程序的邏輯模型和物理模型,以及確保實現方案包含的安全功能清單。擁有了這些以及目標聲明和用戶方案,我們可以開始這次「編碼前」探險的最後一部分了。完成設計文檔

在直接進入項目的編碼部分之前,需要花一點時間實際勾畫出應用程序的邏輯組件,這非常重要。在我們的示例解決方案中,我們要實現解決方案的三個邏輯組件:數據庫、.NET 數據訪問組件和 ASP.NET 用戶界面。在下面幾篇文章中,我們將非常具體地介紹如何實現這些組件。但現在,我們只是勾畫出每個組件的大致輪廓,討論過程中最重要的方面,即文檔化組件間的交互。

數據庫

對于 DotNetKB 應用程序,我們需要將數據存儲在三張表中:主題、問題和回答(請參閱下圖)。

應用程序規劃與設計 [1]

圖 3:主題、問題和回答表

我們需要使用存儲過程,以使中間層組件也可以安全地訪問數據。有關數據庫的細節,我們將在下一篇文章中討論。這裏,我們只是指出:列出表名稱及所有列細節、默認索引和存儲過程列表的數據庫文檔,應該包含在一個完整的數據庫設計文檔中。即,文檔中應該具有成功實現系統數據存儲部分所需的具體信息。

注重:假如留心的話,您可能會注重到我們未提及將專家數據存儲在數據庫中。只是爲了使項目更加有趣(同時給我們一個機會使用直接 XML 數據存儲),我們將專家信息存儲在一個 XML 數據文件中。

數據訪問組件

數據訪問組件設計文檔描繪與數據存儲系統的交互以及與用戶界面的交互的所有細節。在有些系統中,數據訪問組件實際上是處理過程中各種問題的多個程序集。例如,可能會有一系列業務規則呈現在與數據存儲和檢索完全獨立的用戶界面上。在這種情況下,將業務組件與數據訪問組件分開實現可能比較明智。

在我們的示例中,實際實現的是兩個單獨的組件:Message 組件和 Dataaccess 組件。假如在支持基于 XML 的數據的傳輸服務(例如 SOAP Web Service)中進行規劃,這種面向消息的實現方案將會非凡有成效。

消息組件

消息組件定義一系列用于在各圖層之間傳輸數據的類。這些消息可以作爲二進制或 XML 文本數據存在。消息圖層的價值在于:保護系統的其余部分,使其獨立于數據存儲實現方案的具體細節,例如 SQL Server、XML 文件等。此外,通過實現消息圖層而不是更複雜的「智能對象」庫,我們的解決方案可以更輕松地支持那些不能同時發送數據和類級別邏輯的遠程調用服務,例如 XML-SOAP。

下面是一個消息類示例,在該示例中實現了 Topic 消息及其集合:Public Class Topic

Private _ID As Integer

Private _Title As String

Private _Description As String

Public Property ID() As Integer

Get

Return _ID

End Get

Set(ByVal Value As Integer)

_ID = Value

End Set

End Property

Public Property Title() As String

Get

Return _Title

End Get

Set(ByVal Value As String)

_Title = Value

End Set

End Property

Public Property Description() As String

Get

Return _Description

End Get

Set(ByVal Value As String)

_Description = Value

End Set

End Property

End Class

Public Class Topics

Inherits System.Collections.CollectionBase

Default Public Property Item(ByVal index As Integer) As Topic

Get

Return CType(List(index), Topic)

End Get

Set(ByVal Value As Topic)

List(index) = Value

End Set

End Property

Public Function Add(ByVal s As Topic) As Integer

Return List.Add(s)

End Function

Public Sub Remove(ByVal index As Integer)

List.Remove(index)

End Sub

End Class

注重:假如您已嘗試過面向消息的設計,便會了解我們想要使這些消息類系列化,以便在應用程序圖層之間輕松地往返發送。幸運的是,.NET 運行時知道如何進行這項操作,而無需我們做過多的工作。但是,當我們學習創建消息的文章時,我們將具體討論 .NET 運行時如何系列化類,以及我們如何進行操作以使代碼中的過程最優化。

在後面實現消息組件和數據訪問組件時,文章中將介紹此方法的細節。設計文檔將包含一個由所有信息及其屬性與數據類型組成的列表。現在,我們只是考慮如何使用此消息方法來封裝圖層間的數據傳輸,如何創建一種與本地方案和遠程方案配合使用的常規數據服務。

數據訪問組件

定義消息類的概念後,數據訪問組件可以集中精力處理與數據存儲系統直接對話的細節,並以正確的消息格式返回信息。在我們的示例中,這將涉及到使用來自用戶界面的請求映射 SQL Server 存儲過程,並創建可返回到用戶界面進行顯示的消息(或消息集合)。

例如,下面是一個數據訪問組件的一部分示例代碼,該組件將從數據存儲中檢索單個 Topic 記錄,並將正確的消息格式返回到用戶界面。Public Function GetTopicRecord(ByVal ID As Integer) As Messages.Topic

Dim t As Messages.Topic = New Messages.Topic

cn = New SqlConnection(secureConnectionString)

cd = New SqlCommand("GetTopic", cn)

cd.CommandType = CommandType.StoredProcedure

cd.Parameters.Add("@ID", ID)

cn.Open()

dr = cd.ExecuteReader()

dr.Read()

With t

.ID = ID

.Title = dr("Title")

.Description = dr("Description")

End With

Return t

End Function

設計文檔將包括一系列用于處理來自用戶界面的各個請求的類和方法,並含有有關調用哪個存儲過程以及返回何種消息格式的具體信息。同樣,我們將在後面主要介紹數據訪問圖層的文章中討論此過程的細節。

Web 用戶界面

最後,用戶界面設計文檔將包括完成各種方案所需的所有用戶輸入和顯示。通常來說,用戶界面文檔包括界面機制的細節以及使用戶界面呈現唯一性的圖形設計元素。例如,配色方案、字體和總體頁面設計,與用于獲取搜索查詢的正確數據的輸入名稱和輸入數量一樣重要。

要使文檔簡潔,通常在一個與圖形設計單獨的文檔中概要描述機制細節。這是我們將要在示例中做的工作。在後面的一篇文章中,我們將創建一個綜合性用戶界面文檔和實現方案,具體說明每個屏幕的元素和相關操作。在另一篇文章中,我們將處理應用程序有關圖形的各個方面,重點討論作爲一種外觀服務的級聯樣式表的使用。

下面是一個典型的用戶界面描述,它涉及「主題」編輯方案。

主題輸入屏幕

「主題」屏幕將顯示所有當前主題(主題 ID 和主題名稱)的一個縮略列表,在每個主題旁邊還將顯示一個「編輯」鏈接。單擊「編輯」鏈接將會調用關聯的主題記錄並將其顯示在一系列的輸入框中。「標題」和「描述」是可編輯的,而「主題 ID」是只讀的。用戶可以編輯標題和描述,然後按「保存」按鈕將更改寫入數據存儲。輸入將被驗證。兩者都是必需的輸入項,「標題」的長度限制爲 30 個字符,「描述」的長度限制爲 500 個字符。更新完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。

用戶還可以刪除現有的主題記錄,方法是單擊列表中的「編輯」鏈接,審核顯示屏幕上的記錄細節後,單擊「刪除」鏈接。刪除完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。請注重,用戶不能刪除與現有問題或回答相關聯的主題。

此外,用戶可以完整地添加新主題記錄,方法是在初始顯示屏幕上單擊「新建主題」鏈接。將顯示「標題」和「描述」輸入(不顯示 ID 輸入)並提供一個「保存」按鈕。輸入將被驗證。兩者都是必需的輸入項,「標題」的長度限制爲 30 個字符,「描述」的長度限制爲 500 個字符。更新完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。

利用上面的敘述,您可以輕松地實現一個完整的功能屏幕。判定一個好的設計文檔的方法是:它能夠使讀者完成工作,且不會提出額外的問題。最終的用戶界面設計文檔將包括應用程序中每個屏幕的此類敘述。小結並付諸行動

我們簡要介紹了數據庫、中間層和用戶界面實現方案的最終設計文檔。加上體系結構和初始規劃文檔,它們形成了我們的完整設計包。在實際的情況中,即使是最小的系統,完成這些文檔也至少需要幾個小時。對于大型系統,可能需要幾周甚至可能幾個月的時間。有些人可能會對此有一點挫敗感,但是通過事先完成這些工作,您可以在進入項目的編碼階段之前很早就了解完成解決方案面臨的幾乎所有主要障礙。這樣可以減少編寫實際代碼的時間,並且還可以減少您會碰到的錯誤和障礙的數量。

在下一篇文章中,我們將討論使用 Visual Studio .NET 在 SQL Server 中建立數據存儲系統的有關細節。我們將定義數據表,創建必需的存儲過程,並設置正確的數據訪問,以確保任何組件和數據本身之間具有安全可靠的連接。

至此,您已經看到了一個如何創建應用程序規劃的可用示例,可以開始考慮如何在您自己的工作中使用這些元素來提高項目的整體質量和生産率。有關項目規劃以及規劃如何影響軟件質量的具體信息,請參閱 Steve McConnell 的 Software Project Survival Guide。

Mike Amundsen 提供培訓、演講和咨詢服務。要了解他的具體信息或與他聯絡,請訪問他的站點 http://amundsen.com/。此外,還可以在 http://www.amundsen.com/DotNetKB 站點上找到本文的更新和相關資料。

摘要:了解如何規劃和設計 asp.net 應用程序。本文以一個知識庫 Web 應用程序爲例,討論實際應用程序創建實踐中最常見的幾個因素。(本文包含一些指向英文站點的鏈接。) 目錄 簡介 規劃基本 ASP.NET 應用程序 定義應用程序體系結構 安全規劃 完成設計文檔 小結並付諸行動簡介 歡迎來到「進入 ASP.NET 世界」。在隨後的幾周或幾個月中,本系列文章將逐步具體介紹如何使用 Microsoft® ASP.NET 和 Microsoft Visual Studio® .NET 來設計、實現和部署典型的 Web 應用程序,以探討實際應用程序創建實踐中最常見的幾個因素。我們不僅僅布置一些 Web 窗體,也不局限于只對後端數據庫進行一些數據綁定。數據綁定和 Web 窗體布局很重要,但是有許多其他問題也非常重要。 例如,無論采用何種目標平台或語言,所有經過良好編碼的項目都包括一些基本的規劃步驟,例如目標聲明、用戶方案文檔,甚至用于標識解決方案的物理邊界和邏輯邊界的體系結構文檔。此外,在解決方案生命周期的早期就將安全規劃包含在內是一種非常好的習慣。這些內容與良好的數據庫模型、精心設計的中間件組件以及簡潔的用戶界面設計一起,可以確保您最終在生産中部署的應用程序是安全的、可靠的,並且是用戶友好的。 此時,一些讀者可能會認爲本文屬于那些基調很高的文章,目標定位在某些超大型企業級方案,而這種方案根本不適用于一般的小工廠、愛好者或個人開發團體。其實並不是這樣!即使只是創建您自己個人使用的基于 Web 的小型解決方案,從一開始就進行完善的規劃將有助于確保流程最終的輕松實現和部署。而且,並不是高級的程序員或 Web 開發人員才可以使用這些技術。無論您的技術水平如何,也無論您屬于哪類目標讀者,我相信您都會發現這一系列文章對您很有幫助,它爲您提供了豐富的信息,而且(請答應我這樣說)十分有趣。 我們將生成一個稱爲 DotNetKB 的示例知識庫 Web 應用程序,這個過程將貫穿整個系列文章。在作爲第一篇文章的本文中,我們將介紹典型項目的設計階段,包括基本規劃、應用程序體系結構和實現方案設計。學習完本文後,您將已經預備好所有的文檔,並會迫不及待地希望開始創建解決方案。 預備工作非常簡單,我們跳過這部分內容,直接開始第一步「應用程序規劃」。規劃基本 ASP.NET 應用程序 使用 Visual Studio .NET 創建基于 Web 的 ASP.NET 應用程序的第一步是制定基本的應用程序規劃 (AP)。制定規劃不僅對于由多個開發人員建立的大型解決方案而言是必不可少的,而且即使對于最小的應用程序,一個完善的 AP 也是非常重要的。創建 AP 有助于您在開始編碼「之前」就能仔細考慮一些常見問題。這樣,您可以在應用程序生命周期的早期便完全了解挑戰和解決方案,而不是在完全陷入窘境之後才發現問題。在《Software PRoject Survival Guide》一書中,作者 Steve McConnell 指出:在軟件項目後期糾正錯誤所花的成本與在早期階段發現並糾正這些錯誤所花的成本相比,前者可能是後者的 50 - 200 倍。 一個完善的項目規劃包含哪些內容?可以包含許多內容,但最基本的是要包含目標聲明和一系列用戶方案。還有其他很多有用的資料,包括需求文檔、編碼標准、交付進度、測試過程等。對于我們要建立的簡單示例解決方案,將主要介紹簡單的應用程序聲明和一些用戶方案。同時還將解決一些其他問題。 應用程序聲明 此系列文章要建立的項目(稱爲 DotNetKB)是一個簡單的知識庫 Web 站點,在這個站點中,用戶可以提各種問題,並可以得到授權「專家」的回答。這樣,以後訪問者在查找常見 ASP.NET 問題的解決方案時,可以對得到的結果數據進行搜索和過濾。 這是對我們的 DotNetKB 項目的一個基本目標聲明。DotNetKB 是一個基于 Web 的應用程序,它可以列出訪問者提出的一系列問題,並顯示授權專家對這些問題作出的回複。訪問者可以向系統添加新問題,並可以按照問題的主題、問題和/或回答中的要害字來搜索和過濾這些問題。訪問者還可以按主題或按添加到系統中的日期來對問題列表進行排序。 授權專家可以登錄到應用程序中已設置安全機制的部分,審閱問題,添加、編輯和刪除對一個問題的一個或多個回答。應用程序治理員還可以建立專家登錄權限和登錄配置文件,以及添加、編輯和刪除問題主題。 此外,還提供了一些基本統計信息,包括系統中問題和回答的數量,以及每個專家的回複數量和至今已被訪問的頁面數量。 正如您從上面的聲明中看到的那樣,該解決方案非常簡單。在閱讀目標聲明時,您可能會開始考慮可以添加到這個應用程序的許多其他功能,以使應用程序更加強大。這說明了項目目標聲明的一個主要依據,即避免「功能蔓延」。我們都清楚,假如更改最終結果本來基于的概念,簡單的想法將導致非常龐大且歪曲的結果。有句老格言:「假如不知道要去往何方,你可能會在某個地方停下來」,它原本揭示的是夏季公路旅行,其道理同樣可用于軟件項目。 一些項目的目標聲明中可能需要包含更多的信息。而對于我們的使用,上面的目標聲明就符合要求。現在我們對于要完成的應用程序有了一個清楚的熟悉,接下來需要一些具體的信息來描述用戶如何與系統交互以及用戶需要執行哪些任務來完成目標。我們需要一系列用戶方案。 文檔化用戶方案 用戶方案沒有什麽令人驚異之處。通常,它們只是描述用戶如何與應用程序交互。用戶方案的要害價值在于記錄了關于每個人對用戶希望系統如何運行以及應用程序應如何響應的設想。通過完成這個過程,您將可以完全了解處理各種用戶與系統的交互時所需的數據點和函數。換句話說,編寫完善的用戶方案將有助于您確定完成解決方案需要實現的數據庫、中間件和用戶界面元素。 注重:Visual Studio .NET Enterprise Architect 有一項非常不錯的功能,即答應您使用 Microsoft Visio® 通過 UML(統一建模語言)創建用戶方案,然後生成這些方案的基本代碼。在這裏,我不打算深入探討這些細節,但是您可以在 MSDN® Academic Alliance 站點找到一篇關于這一主題的好文章 Generating .NET Code Using Visio Enterprise Architect's UML,作者是 Sreedhar Koganti。 有了上一節的目標聲明後,下面是 DotNetKB 項目的幾個示例用戶方案。 搜索知識庫 匿名用戶可以輸入一個或多個要害字並執行搜索,搜索將返回包含這些要害字的問題和/或回答列表。用戶可以將要害字搜索鎖定在僅搜索問題、僅搜索回答或者二者都搜索。返回的列表將顯示問題及其回複數和被其他用戶訪問的次數。單擊鏈接將返回以時間先後逆序排列的回複(純文本)列表。 將新問題輸入到知識庫中 匿名用戶可以浏覽用于向數據庫輸入新問題以供授權專家審閱和回複的屏幕。用戶可以輸入問題的標題和內容,並可以選擇在一系列主題中的某個主題下記錄該問題。用戶還可以輸入他們的名字和相關的 URL(電子郵件、Web 地址等)。輸入將被驗證,以確保包含必需的數據並確保所有輸入數據不會受到腳本攻擊等。一旦數據經過驗證並被保存到數據庫中,用戶將看到一個響應屏幕,感謝用戶的支持並將用戶直接連接到主頁。此外,用戶還可以選擇讓該站點「記住」他們的姓名和 URL 以備以後訪問該站點時使用。 您已經了解它的工作原理了,對嗎?每一個方案都嘗試細化用戶交互的重要方面。例如,上面列出的兩個方案表明用戶爲「anonymous」(匿名用戶),這表示這類用戶不需要登錄或進行其他方式的授權。第二個示例還標識了若幹輸入值、驗證步驟和可選操作。 當然,這只是兩個示例;完整的系統需要更多的方案。此外,需要非凡注重的是,「用戶」不僅僅可以是人,也可以是您的程序需要與其通信的其他應用程序,甚至還可以是您的應用程序的其他部分。例如,一個方案描述主頁如何列出最近添加到知識庫中的內容,以供任何人查看。此例中的「用戶」將是主頁自身。還有一些方案描述專家如何查找和回複新問題以及治理員如何更新主題列表並治理系統的其他部分。我已爲討論這個簡單的應用程序標識了 20 多種方案。您可以在 DotNetKB 中找到當前列表(以及與此項目相關的所有其他資料)。 至此我們就有了目標聲明和一些用戶方案。現在,是時候稍憩一下,然後學學一些技術了。我們需要定義應用程序體系結構,這可以幫助我們以「鮮活有效的代碼」實際實現方案。定義應用程序體系結構 有了基本的目的和爲解決方案開發的用戶方案列表後,您需要開始籌劃整體的體系結構。主要目標是標識應用程序的邏輯方面和物理方面,即如何將應用程序拆分爲各種有用的部分。在本節中還添加了安全性方面的內容。安全是在規劃的「一開始」您就需要考慮的問題,而不是在開發周期中「最後添加」的內容。我們稍後會在本節中具體討論這個問題。 邏輯體系結構 從邏輯上講,您需要規劃解決方案以標識數據存儲、數據訪問、業務規則、用戶界面等之間的「邊界」。通常,Web 開發人員會選擇一個兩階段模型,並用 Web 窗體存儲用于訪問現有數據存儲系統(例如 Microsoft SQL Server)的所有代碼。一個更有效的方法是創建一個位于 Web 窗體用戶界面與 SQL Server 數據存儲系統之間的中間層組件庫。這種三層方法(Web 窗體、組件、數據庫)通常是大多數應用程序所需的。但是,在某些情況下,可能需要一個其他層來處理服務器之間傳輸的數據。這個傳輸層可以使用獨立于平台的協議(例如 xml-SOAP)來實現。但是,假如您從頭到尾都使用 Microsoft .NET 技術,則可以使用 .NET 遠程協議的二進制版來完成這一任務,而且速度比使用 XML-SOAP 要快得多。 對于我們的示例,我們將定義三個邏輯邊界:用戶界面(Web 窗體)、中間層(一個 .NET 組件程序集)和數據層(SQL Server 數據庫)。圖 1 顯示了如何表示這一內容。 [url=/bbs/detail_1783385.html][img]http://image.wangchao.net.cn/it/1323430334850.gif[/img][/url] 圖 1:三層圖 現在我們有一個簡單的邏輯模型。它是如何起作用的?它有助于我們考慮各個邏輯組之間的邊界。每個邏輯層應盡量與其他層獨立。理想的情況是,圖層中的更改應該對整體産生最小的影響。例如,假如將數據存儲從 SQL Server 更改到 XML 數據文件,唯一受到影響的圖層應是中間層圖層。用戶界面應該根本無需考慮更改。這會使您進行思考:如何實現解決方案的實際編碼以實現此原則。 另外,邏輯層有助于我們考慮安全問題。各個圖層之間的邊界都存在潛在的安全漏洞。而且,各個圖層可能有自己特定的安全措施(SQL Server 權限、.NET 運行時權限、ASP.NET 安全等)。同樣,我們稍後會在本節中具體討論這個問題。 物理體系結構 確定邏輯層後,考慮物理層也很重要。例如,您可以在同時安裝有 SQL Server、Internet Information Server、ASP.NET 和 .NET 運行時的單個實際計算機上實現這個應用程序。這將是一個物理層。但更可靠且可擴展的方法是:在由三個 Web 服務器組成的簇上部署 Web 窗體,在兩個應用服務器上部署 .NET 組件程序集,在兩個故障恢複模式的 SQL Server 上部署數據庫。這樣産生的物理體系結構將七個 Windows 服務器包含在三個主要組中:Web 簇、組件簇和數據庫簇。假如您了解系統的不同邏輯部件可以位于不同的計算機上,您可能會實現不同的代碼。 對于我們的示例,我們采用一個有效且強大的兩層模型:Web 服務器托管用戶界面和組件,數據庫服務器托管 SQL Server 數據存儲。假如通信量非常大,這個模型使我們可以靈活地在簇中添加更多的服務器,並使其保持足夠的簡潔以便于處理。下面的圖像顯示了此物理體系結構與前面定義的邏輯體系結構之間的映射關系。 [url=/bbs/detail_1783385.html][img]http://image.wangchao.net.cn/it/1323430334932.gif[/img][/url] 圖 2:物理體系結構與三層體系結構之間的映射關系 正如您看到的那樣,邏輯體系結構和物理體系結構不必相同。在規劃階段還要考慮一項內容:安全。安全規劃 Microsoft 有一個關于安全性與軟件這一主題的歌訣:「Secure by design, secure by default, and secure by deployment(設計安全,默認安全和部署安全)」。即,在安全中設計,期待系統在默認情況下是安全的,以及創建可以在安全環境中成功部署的解決方案。安全始終是重要的。既然越來越多的軟件要在公用的 Internet 上「生存」,編寫安全的軟件就更加要害。對于我們而言,幸運的是,.NET 運行時和 Windows 操作系統提供廣泛的安全選項和功能,我們可以輕松地將其包含在我們的應用程序中。無需過分注重標識和消除聯機解決方案中安全漏洞的細節,我們可以指出其中一些最常見的漏洞並指出我們的應用程序規劃如何進行處理。 注重:有關可用選項的具體信息,請參閱 Microsoft Security Developer Center。 緩沖區溢出 這可能是已編譯應用程序中最常見的安全漏洞。由于我們將使用 .NET 運行時,而它是設計用來在內存中安全運行的,因此不太可能發生緩沖區溢出。此外,我們使用 Microsoft Visual Basic® .NET 對解決方案進行編碼,而 Microsoft Visual Basic® .NET 不像 C 或 C++ 那樣輕易受到緩沖區溢出問題的影響。但是,即使我們打算用 C++ 創建組件,我們還可以使用編譯程序的非凡功能,GS 轉換,來保護我們免受大多數緩沖區溢出的攻擊。 數據庫攻擊 另一種常見的安全漏洞可能會使惡意用戶獲得訪問存儲在數據庫中的原始數據的權限。爲了防止黑客獲得數據的控制權,我們僅使用 SQL Server 存儲過程,而不使用「內聯查詢」。這樣可以大大減少試圖在輸入流中插入其他 SQL 命令的攻擊。我們還在程序中多個位置處使用輸入驗證,以確保所有輸入僅包含有效的字符。 交叉站點腳本攻擊 對 Web 應用程序進行的常見攻擊還有一種,它涉及到用戶在輸入流中添加客戶方腳本,這類攻擊將執行附加的對話並誘騙用戶將個人數據發送到黑客自己的 Web 站點。要解決這個問題,我們使用 ASP.NET 1.1 的一個新功能,過濾出這種惡意代碼的所有輸入,防止將它置入系統中。顯示屏幕上還包含附加代碼,它將自動禁用任何腳本或顯示可能會插入到數據存儲中的標記。 至此,我們已獲得了應用程序的邏輯模型和物理模型,以及確保實現方案包含的安全功能清單。擁有了這些以及目標聲明和用戶方案,我們可以開始這次「編碼前」探險的最後一部分了。完成設計文檔 在直接進入項目的編碼部分之前,需要花一點時間實際勾畫出應用程序的邏輯組件,這非常重要。在我們的示例解決方案中,我們要實現解決方案的三個邏輯組件:數據庫、.NET 數據訪問組件和 ASP.NET 用戶界面。在下面幾篇文章中,我們將非常具體地介紹如何實現這些組件。但現在,我們只是勾畫出每個組件的大致輪廓,討論過程中最重要的方面,即文檔化組件間的交互。 數據庫 對于 DotNetKB 應用程序,我們需要將數據存儲在三張表中:主題、問題和回答(請參閱下圖)。 [url=/bbs/detail_1783385.html][img]http://image.wangchao.net.cn/it/1323430334975.gif[/img][/url] 圖 3:主題、問題和回答表 我們需要使用存儲過程,以使中間層組件也可以安全地訪問數據。有關數據庫的細節,我們將在下一篇文章中討論。這裏,我們只是指出:列出表名稱及所有列細節、默認索引和存儲過程列表的數據庫文檔,應該包含在一個完整的數據庫設計文檔中。即,文檔中應該具有成功實現系統數據存儲部分所需的具體信息。 注重:假如留心的話,您可能會注重到我們未提及將專家數據存儲在數據庫中。只是爲了使項目更加有趣(同時給我們一個機會使用直接 XML 數據存儲),我們將專家信息存儲在一個 XML 數據文件中。 數據訪問組件 數據訪問組件設計文檔描繪與數據存儲系統的交互以及與用戶界面的交互的所有細節。在有些系統中,數據訪問組件實際上是處理過程中各種問題的多個程序集。例如,可能會有一系列業務規則呈現在與數據存儲和檢索完全獨立的用戶界面上。在這種情況下,將業務組件與數據訪問組件分開實現可能比較明智。 在我們的示例中,實際實現的是兩個單獨的組件:Message 組件和 Dataaccess 組件。假如在支持基于 XML 的數據的傳輸服務(例如 SOAP Web Service)中進行規劃,這種面向消息的實現方案將會非凡有成效。 消息組件 消息組件定義一系列用于在各圖層之間傳輸數據的類。這些消息可以作爲二進制或 XML 文本數據存在。消息圖層的價值在于:保護系統的其余部分,使其獨立于數據存儲實現方案的具體細節,例如 SQL Server、XML 文件等。此外,通過實現消息圖層而不是更複雜的「智能對象」庫,我們的解決方案可以更輕松地支持那些不能同時發送數據和類級別邏輯的遠程調用服務,例如 XML-SOAP。 下面是一個消息類示例,在該示例中實現了 Topic 消息及其集合:Public Class Topic Private _ID As Integer Private _Title As String Private _Description As String Public Property ID() As Integer Get Return _ID End Get Set(ByVal Value As Integer) _ID = Value End Set End Property Public Property Title() As String Get Return _Title End Get Set(ByVal Value As String) _Title = Value End Set End Property Public Property Description() As String Get Return _Description End Get Set(ByVal Value As String) _Description = Value End Set End Property End Class Public Class Topics Inherits System.Collections.CollectionBase Default Public Property Item(ByVal index As Integer) As Topic Get Return CType(List(index), Topic) End Get Set(ByVal Value As Topic) List(index) = Value End Set End Property Public Function Add(ByVal s As Topic) As Integer Return List.Add(s) End Function Public Sub Remove(ByVal index As Integer) List.Remove(index) End Sub End Class 注重:假如您已嘗試過面向消息的設計,便會了解我們想要使這些消息類系列化,以便在應用程序圖層之間輕松地往返發送。幸運的是,.NET 運行時知道如何進行這項操作,而無需我們做過多的工作。但是,當我們學習創建消息的文章時,我們將具體討論 .NET 運行時如何系列化類,以及我們如何進行操作以使代碼中的過程最優化。 在後面實現消息組件和數據訪問組件時,文章中將介紹此方法的細節。設計文檔將包含一個由所有信息及其屬性與數據類型組成的列表。現在,我們只是考慮如何使用此消息方法來封裝圖層間的數據傳輸,如何創建一種與本地方案和遠程方案配合使用的常規數據服務。 數據訪問組件 定義消息類的概念後,數據訪問組件可以集中精力處理與數據存儲系統直接對話的細節,並以正確的消息格式返回信息。在我們的示例中,這將涉及到使用來自用戶界面的請求映射 SQL Server 存儲過程,並創建可返回到用戶界面進行顯示的消息(或消息集合)。 例如,下面是一個數據訪問組件的一部分示例代碼,該組件將從數據存儲中檢索單個 Topic 記錄,並將正確的消息格式返回到用戶界面。Public Function GetTopicRecord(ByVal ID As Integer) As Messages.Topic Dim t As Messages.Topic = New Messages.Topic cn = New SqlConnection(secureConnectionString) cd = New SqlCommand("GetTopic", cn) cd.CommandType = CommandType.StoredProcedure cd.Parameters.Add("@ID", ID) cn.Open() dr = cd.ExecuteReader() dr.Read() With t .ID = ID .Title = dr("Title") .Description = dr("Description") End With Return t End Function 設計文檔將包括一系列用于處理來自用戶界面的各個請求的類和方法,並含有有關調用哪個存儲過程以及返回何種消息格式的具體信息。同樣,我們將在後面主要介紹數據訪問圖層的文章中討論此過程的細節。 Web 用戶界面 最後,用戶界面設計文檔將包括完成各種方案所需的所有用戶輸入和顯示。通常來說,用戶界面文檔包括界面機制的細節以及使用戶界面呈現唯一性的圖形設計元素。例如,配色方案、字體和總體頁面設計,與用于獲取搜索查詢的正確數據的輸入名稱和輸入數量一樣重要。 要使文檔簡潔,通常在一個與圖形設計單獨的文檔中概要描述機制細節。這是我們將要在示例中做的工作。在後面的一篇文章中,我們將創建一個綜合性用戶界面文檔和實現方案,具體說明每個屏幕的元素和相關操作。在另一篇文章中,我們將處理應用程序有關圖形的各個方面,重點討論作爲一種外觀服務的級聯樣式表的使用。 下面是一個典型的用戶界面描述,它涉及「主題」編輯方案。 主題輸入屏幕 「主題」屏幕將顯示所有當前主題(主題 ID 和主題名稱)的一個縮略列表,在每個主題旁邊還將顯示一個「編輯」鏈接。單擊「編輯」鏈接將會調用關聯的主題記錄並將其顯示在一系列的輸入框中。「標題」和「描述」是可編輯的,而「主題 ID」是只讀的。用戶可以編輯標題和描述,然後按「保存」按鈕將更改寫入數據存儲。輸入將被驗證。兩者都是必需的輸入項,「標題」的長度限制爲 30 個字符,「描述」的長度限制爲 500 個字符。更新完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。 用戶還可以刪除現有的主題記錄,方法是單擊列表中的「編輯」鏈接,審核顯示屏幕上的記錄細節後,單擊「刪除」鏈接。刪除完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。請注重,用戶不能刪除與現有問題或回答相關聯的主題。 此外,用戶可以完整地添加新主題記錄,方法是在初始顯示屏幕上單擊「新建主題」鏈接。將顯示「標題」和「描述」輸入(不顯示 ID 輸入)並提供一個「保存」按鈕。輸入將被驗證。兩者都是必需的輸入項,「標題」的長度限制爲 30 個字符,「描述」的長度限制爲 500 個字符。更新完成後,將顯示一條響應消息指出已確認更新;假如更新失敗,則顯示一條消息指出錯誤狀況。 利用上面的敘述,您可以輕松地實現一個完整的功能屏幕。判定一個好的設計文檔的方法是:它能夠使讀者完成工作,且不會提出額外的問題。最終的用戶界面設計文檔將包括應用程序中每個屏幕的此類敘述。小結並付諸行動 我們簡要介紹了數據庫、中間層和用戶界面實現方案的最終設計文檔。加上體系結構和初始規劃文檔,它們形成了我們的完整設計包。在實際的情況中,即使是最小的系統,完成這些文檔也至少需要幾個小時。對于大型系統,可能需要幾周甚至可能幾個月的時間。有些人可能會對此有一點挫敗感,但是通過事先完成這些工作,您可以在進入項目的編碼階段之前很早就了解完成解決方案面臨的幾乎所有主要障礙。這樣可以減少編寫實際代碼的時間,並且還可以減少您會碰到的錯誤和障礙的數量。 在下一篇文章中,我們將討論使用 Visual Studio .NET 在 SQL Server 中建立數據存儲系統的有關細節。我們將定義數據表,創建必需的存儲過程,並設置正確的數據訪問,以確保任何組件和數據本身之間具有安全可靠的連接。 至此,您已經看到了一個如何創建應用程序規劃的可用示例,可以開始考慮如何在您自己的工作中使用這些元素來提高項目的整體質量和生産率。有關項目規劃以及規劃如何影響軟件質量的具體信息,請參閱 Steve McConnell 的 Software Project Survival Guide。 Mike Amundsen 提供培訓、演講和咨詢服務。要了解他的具體信息或與他聯絡,請訪問他的站點 http://amundsen.com/。此外,還可以在 http://www.amundsen.com/DotNetKB 站點上找到本文的更新和相關資料。
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有