本文章是由機器翻譯。
技術最前線
資料的優缺點傳送物件
Dino Esposito
內容
BLL 的程序模式
物件根據 BLL 的模式
服務層
簡介資料傳輸物件
DTOs 的其他優點
DTOs 的缺點
直接參考的項目
中間的方式
混合的方法
幾乎每個開發人員和架構設計人員會同意下列,不過相當遺失,定義的商務邏輯層 (BLL) 的軟體應用程式: [BLL 屬於的軟體應用程式所處理的商務相關的工作效能。 嘗試問題網域中的模型實體的資料操作中 BLL 的程式碼 — 發票、 客戶、 訂單及類似。 模型的商務程序 BLL 嘗試的作業。
這個主要是可接受的定義底下介於數機碼的定義和未指定的詳細資料。 設計模式 」 有幫助架構設計人員和轉換成藍圖鬆散定義的程式碼設計工具。 在就一般 BLL 設計模式是稍微時有不同的焦點。 這些模型作業和資料,且通常做為設計 BLL 的起始點。
此的文件中簡短重新整理程式的組織 BLL,程序和物件為基礎的模式後我將著重於問題的一方) 資料傳輸物件),如果無法有效地解決架構層可能會有一個深影響專案的開發。
BLL 的程序模式
設計 BLL 時,您可以從有一種出現在分析階段期間,使用案例中啟動。 通常,您最後得到撰寫程式碼的使用者和系統之間每次需要互動的方法之一。 每次互動表單邏輯包含所有的交易因為步驟 — 從收集到執行此項工作的輸入和重新整理使用者介面的存取資料庫。 這種方法被指交易指令碼 (TS) 模式。
TS,您專注於所需的動作並不真的建置為重力中心的應用程式的概念模型的網域。
若要移動資料,您可以使用任何可能符合您的容器物件。 在 Microsoft.NET 的空間這通常表示使用 ADO.NET 資料容器,例如資料集和 DataTables。 這些物件是一種具有某些搜尋索引,以及篩選功能 [super-array] 物件。 此外,您可以是資料集和 DataTables 輕鬆地序列化跨層,甚至保存在本機啟用離線案例。
TS 模式並不會強制特定模型的資料表示 (和不會防止任何可能)。 通常,作業群組是一或多個進入點的類別中的靜態方法。 或者,作業可以實作為一個命令模式的方法中的命令。 組織的資料存取保留給程式開發人員,且通常會產生的 ADO.NET 程式碼區塊。
TS 模式是相當簡單,若要設定 ; 在此同時它顯然並不會縮放,也隨著應用程式的複雜度的增加。 在.NET 的空間,另一種模式已取得這些年來的寬接受: 表格單元模式。 在一個簡單地說表格單元模式建議以資料庫為中心的願景,BLL。 它會要求您建立商務元件為每個資料庫資料表。 稱為資料表的模組類別,商務元件封裝行為與資料一起。
表格單元模式中, BLL 分成每個代表的整個資料庫資料表的一組鬆散的元件。 被嚴格的表格方向,表格單元模式適合使用類似的資料錄集的資料結構的傳遞資料。 ADO.NET 資料容器 ADO.NET 較佳的但,自訂和具型別版本是自然的選擇。
需要更多概念性的問題領域檢視時 BLL 模式過多年來,在.NET 環境中,需要其他發展。 架構設計人員通常若要建置的實體/關係模型,表示問題領域,然後查看 LINQ 以 SQL 和 Entity Framework 等技術的具體的工具,來幫助。
物件根據 BLL 的模式
表格單元模式為基礎的物件,但不是真正的物件架構模式模型的商務邏輯。 沒有物件,但代表不代表問題的網域物件的資料表的物件。
中的物件導向的設計,商務邏輯會識別實體,並表示所有的允許及必要實體之間的互動。 最後,應用程式是以一組相互關聯和 interoperating 物件的檢視。 對應至實體,加上執行計算表單的某些特殊物件網域模型物件的集合。 (在實體 Framework,您表示使用實體資料模型 [EDM] 的領域模型)。
有各種等級的網域模型中的複雜性,建議不同的模式 (通常是使用中的記錄模式] 或 [網域模型模式。 這種複雜性的好量值是實體模型,請記得在有您想要建立儲存資料的關聯式資料模型間距。 簡單的網域模型是在其中您實體對應密切資料模型中的資料表。 不讓簡單模型需要對應至載入和儲存至關聯式資料庫的網域物件。
使用中的記錄模式是理想的選擇,當您需要簡單的網域模型時,; 否則設定實體與關係不論任何資料庫概念較佳時,網域模型模式便是能夠執行。
使用中的記錄模式很類似您從 LINQ 以 SQL 物件模型 (和 defaultgenerated 模型使用實體設計工具中實體架構 1.0 版) 取得的項目。 您從現有的資料庫,建立對應資料庫資料表的資料列的物件。 物件必須為每個資料表的資料行相同的型別與相同的條件約束的一個屬性。 原始的形式,使用中的記錄模式的建議每個物件會本身負責自己持續性。 這表示每個實體類別應包含方法如儲存和 [載入]。 Entity Framework 都 LINQ,SQL 會透過整合式 O/RM 基礎結構,作為實際的資料存取層,如 圖 1 ] 所示兩個委派持續性。
[圖 1 A 分層的架構 – BLL 的 [網域模型 PatternUsed
服務層
在 [圖 1 ,您會看到 BLL 命名為 「 服務層"坐在展示層和負責的持續性的圖層之間的邏輯區段。 中,簡單地說服務層定義的介面,展示層來觸發預先定義的系統動作。 服務層減少簡報和商務邏輯,並代表在呼叫 BLL 展示邏輯的外貌。 服務層會自己的工作,不論如何將商務邏輯的內部組織。
.NET 程式開發人員為您已相當熟悉 Web 或 Windows 表單中的事件處理常式。 標準的 Button1_Click 方法屬於展示層,而使用者已按一下特定的按鈕之後,表示系統的行為。 系統的行為 — 更就完全您正在實作使用案例,可能需要某些互動 BLL 元件。 通常,您要具現化 BLL 元件,然後編寫指令碼。 指令碼元件所需程式碼可能是呼叫建構函式和可能是一種方法一樣簡單。 更就常不過,這類程式碼是相當豐富的分支,可能需要呼叫多個物件,或等候回應。 大部分的開發人員會指向作為應用程式邏輯的這段程式碼。 因此,服務層是在您儲存應用程式的邏輯時讓它維持不同且網域邏輯分開 BLL 的地方。 網域邏輯是您摺疊到網域實體表示之類別的任何邏輯。
在 [圖 1 ,服務層和網域模型區塊是 BLL 的不同部分,雖然它們可能屬於不同的組件。 服務層知道網域模型,並參考對應的組件。 組服務層件,而,從展示層參考和代表唯一連絡人任何展示層之間的點 (Windows、 Web、 Silverlight 或行動時才是它),BLL。 [圖 2 ] 顯示圖形的連接不同的執行者的參考。 服務層的展示層和 BLL 的其餘部分之間的暫留處理器中取得。 就等它將保持它們張能夠恰好置入分隔但彈性,讓它們完全能夠進行通訊。 在 [ 圖 2 ,展示層並不會保留網域模型的組件的任何參考。 這是主要設計選擇最分層的解決方案。
[圖 2 的參與者演員間的參考的圖表
簡介資料傳輸物件
當您以網域為基礎的願景,應用程式的您不能幫助,但看起來嚴重資料傳輸物件。 根據 LINQ to SQL 或 Entity Framework 不多層式解決方案是免於此設計問題。 但問題是,方式會移動資料與在展示層? 放入另一種方式,應該在展示層保留網域模型的組件參考? (在 Entity Framework 的案例網域模型的組件是出 EDMX 檔的建立該 DLL)。
在理想的情況下,設計應該看起來像 [圖 3 ,made-to-measure 物件用來從展示層傳遞資料,至 [[服務] 圖層的位置,並備份。 這些臨機操作的容器物件取得資料傳輸物件 (DTOs) 的名稱。
[圖 3 簡報層之間通訊 andService 層
一個 DTO 是只公開屬性的容器類別,但沒有方法。 每當您需要傳遞資料的臨機操作結構中的群組值時,一個 DTO 很有用。
以純設計觀點 DTOs 是一個解決方案真的接近完美。 若要進一步將簡報從服務層和領域模型 DTOs 說明。 當使用 DTOs 時,在展示層和服務層共用資料合約,而不是類別。 資料合約是基本上中性表示的相互作用的元件交換資料。 資料合約說明的資料元件接收,但它不是一個特定的系統] 類別的類似的實體。 每日結尾資料合約雖然是一的類別,但並更像特別建立特定服務方法的協助程式類別]。
一層的 DTOs 隔離網域模型,從簡報是鬆散的聯繫性並最佳化的資料傳輸。
DTOs 的其他優點
資料合約採用新增有很大的彈性至 [服務] 圖層] 和 [接下來整個應用程式的設計。 例如,如果使用 DTOs,則強制移動到一個不同的資料量的需求的變更沒有任何影響服務層或甚至網域。 您藉由新增新的屬性修改 DTO 類別相關,但保留之整體的介面的服務層。
應該注意可能簡報的變更表示其中一個使用案例的變更,因此應用程式邏輯中。 由於服務層呈現應用程式邏輯,在此內容中在服務層級介面中的變更是仍可接受的。 但是,在我的經驗中重複的編輯服務層級介面可能會導致錯誤變更網域物件中的結束,實體 — 可能儲存您進一步編輯服務層級中。 在 well-disciplined 小組,或當開發人員有深入了解的領域模型、 服務層,與 DTOs 之間存在的角色分隔,就不會發生這個情況。
如 [ 圖 4 示,DTOs 使用時,您還需要 DTO 介面卡圖層,以適應要不同的介面所需的使用案例的一個或多個實體物件。 您實際實作 「 配接器 」 模式中執行這項作業,— 傳統及最受歡迎的設計模式的其中一個。 介面卡] 模式基本上會將一個類別的介面轉換成另一個用戶端預期的介面。
[圖 4 在 BLL DTO 介面卡
參考 [圖 4 介面卡圖層是負責讀取傳入 OperationRequestDTO 類別的執行個體,以及建立並填入 OperationResponseDTO 的新執行個體。
當需求變更,並強制以 DTO 為基礎的服務層中的變更時,您所要做的只是的更新公用的資料合約的 [DTO 並調整對應 DTO 介面卡。
不要這裡結束 DTOs decoupling 優點。 此外,幸好存留在的簡報中的變更您可以輸入網域模型中的項目變更而不影響您可能需要任何用戶端。
任何真實的網域模型包含關聯性,例如客戶,訂單和訂單-至-客戶,構成客戶和訂單實體之間的雙精度浮點連結。 與 DTOs,您也解決這個問題的管理循環參考的實體物件序列化期間。 若要執行的值,必要時,序列化只可以跨越任何界限一般資料流,可以建立 DTOs。 (我將會傳回至這個時間點一會兒)。
DTOs 的缺點
以純設計觀點 DTOs 是一個實際的好處,但這個理論點確認之後的練習,太呢? 在許多架構開啟點,答案,視情況而定。
網域模型中有數百個實體絕對一個好的原因是 considering 替代方案,以純 DTO 為基礎的方法。 在很多實體的大型專案,DTOs 會加入無層級 (其他) 的複雜性和要執行的工作。 在短一個純 100 %DTO 解決方案是通常只是 100%痛苦解決方案。
雖然通常加入至方案的 DTOs 複雜性測量與網域模型的基數的所需的 DTOs 實際數目可以是更可靠地決定查看使用案例和服務層的實作。 良好的估計需要多少 DTOs 公式是查看服務層中的方法的數目。 數字實數可以是您是否可以跨多個的服務層呼叫重複使用某些 DTOs 較小或更高,如果您 DTOs 群組使用複雜型別一些資料。
在摘要,對使用 DTOs 唯一的引數會是其他的工作所需撰寫和管理產生 DTO 類別的數目。 不,不過,簡單的重要的程式設計師的 laziness。 在大型的專案中 decoupling 從服務層的簡報成本您數百個新的類別。
它應該也注意一個 DTO 並不是只需輕量級您可能需要每個實體的複本。 假設兩個不同的使用案例必須要傳回之訂單的集合 — GetOrdersByCountry 和 GetOrdersByCustomer 說。 很就可能將資訊置於 「 序位 」 是不同。 您可能需要更多 (或更少) 中 GetOrdersByCustomer 比 GetOrdersByCountry 中的詳細資料。 這表示不同 DTOs 為必要。 這個原因數百個實體當然是快速的複雜性,量值,但 DTOs 的實際數量可以由只查看 [使用案例]。
如果 DTOs 並不一定最佳,什麼會是可行的替代方法?
只有替代使用 DTOs 是參考在網域模型從組件中展示層。 以這種方式但是,您建立緊密的聯繫,在圖層之間。 而且緊密結合的層級可能是更糟的問題。
直接參考的項目
第一個、 不-所以-明顯的條件,若要啟用連結的直接從展示層的項目是可接受的展示層來接收資料的實體物件的格式。 有時簡報需要以特定方式格式化資料。 只要 massage 資料所需的用戶端存在 DTO 介面卡圖層。 如果您不使用 DTOs 不過,正確格式化資料的負擔必須移到展示層。 在就其實,以供使用者介面的格式化資料錯誤的位置是網域模型本身。
實際,您可以在不 DTOs 才一起共在展示層和服務層會置在相同處理序中。 在這種情況下您可以輕易地參考實體組件從沒有 thorny 的問題,例如遠端處理和資料序列化處理這兩個層級中。 此考量會導致另一個很好的問題: 位置應該符合服務層?
如果用戶端網頁服務層就會是最好是本機 Web 伺服器裝載頁面。 在 ASP.NET 的應用程式中在展示層是所有在程式碼後置類別,和位於與服務層,在相同的 AppDomain 中一起並排。 在這種案例在展示層和服務層之間的每個通訊就會發生在處理序,並且物件可以共用與沒有進一步 worries]。 ASP.NET 應用程式是良好的案例,您可以嘗試一個解決方案,並不會使用額外的 DTOs 的層級。
technology-wise,您可以實作服務層透過一般的.NET 物件,或透過本機的 Windows 通訊基礎 (WCF) 服務。 如果應用程式是成功,您就可以藉由重新放置到個別的應用程式伺服器的服務層,輕鬆地增加延展性。
如果用戶端桌面應用程式然後服務層通常部署到不同的層,從用戶端遠端存取。 只要用戶端和遠端伺服器分享相同的.NET 平台,您可以使用遠端處理技術 (或,更,WCF 服務) 實作通訊,並仍在兩端使用原生的實體物件。 WCF 基礎結構將處理的封送處理跨層的資料,並幫浦它至原生的實體複本。 而且,在這種情況下您可以排列的架構,並不會使用 DTOs。 如果用戶端和伺服器平台不相容,大幅變更項目。 在這種情況下您有連結原生的物件並叫用它們從用戶端沒有機會 ; 接下來,您在純粹的服務導向案例,且使用 DTOs 是唯一的可能性。
中間的方式
DTOs 是通訊的會影響任何之間簡報和後端系統的實作是通訊的重要的設計選擇的主題。
如果您會使用 DTOs 您保持系統,鬆散結合和各種不同的用戶端向開啟。 如果等您有錢它,DTOs 將會在理想的選擇。 DTOs 新增一個重要程式額外負擔任何實際的系統。 這並不表示不應使用 DTOs,但它們會導致真的可以 prefigure 一個維護的夢魘少數幾百實體物件與更多的使用案例的專案中的類別的一個激增。
如果您在相同時間是提供者和消費者的服務層中,而且如果您在簡報的完整控制權有可能優點中從簡報中參考的實體模型的組件。 以此方式在服務層中的所有方法都允許實體類別作為其簽章的資料合約。 設計和程式碼影響是很清楚地柔和。
是否要使用 DTOs 或不是不容易一般化點。 若要有效,最終決策應該永遠可查看專案的需個別詳細資訊。 最後,以混合的方式可能是情況的您將會做什麼大部分下。 個人,我傾向儘我可以使用項目。 這是不因為我對抗淨化及設計,但一簡單的一種 pragmatism。 具有實體模型,將帳戶只有 10 個項目和幾個使用案例,使用 DTOs 一直不會造成任何重大問題。 而且很棒的設計與低結合。 但是,有上百個項目和使用寫入,類別的實際數種情況下維護,並測試 ominously 方法千分位的順序。 任何可能降低滿足需求的複雜度大於歡迎。
與架構設計人員,但是,您應永遠在以辨識符號表示實體模型及什麼簡報預期是重要或無法涵蓋距離警示。 在這種情況下您應該採取安全 (和更簡潔) DTOs 的路由。
混合的方法
現今的分層應用程式會保留至服務層 BLL 的區段。 (也稱為應用程式層級) 的服務層包含應用程式邏輯 ; 也就是商務規則和程序的特定應用程式,但無法網域。 有多個前端系統會公開單一網域邏輯透過實體的類別,但每個前端然後有它支援的使用案例的特定的額外的商務層。 這是什麼指服務或應用程式層。
從 UI 觸發,應用程式邏輯指令碼服務的商務邏輯與實體。 在服務層中,您實作使用案例,並透過鬆散方法呼叫簡報的公開每個步驟的順序。
在服務層設計,可能會想要套用一些最佳作法、 服從服務導向並共用資料合約,而非實體類別。 當這種方法適合理論上時它通常衝突的真實世界中中,,如它最後會有上百個項目] 和 [使用案例的專案中加入太多的額外負荷。
其實以使用資料的混合的方法協定只有當使用類別是不可能,通常是一個可接受的解決方案。 但為架構設計人員,您必須不讓這項決定輕。 違反良好的設計規則允許,只要您知道您的進行。
有任何疑問或註解郵件寄至 Dino 的 cutting@microsoft.com.
Dino Esposito IDesign 和 co-author Microsoft .NET: Architecting Applications for the Enterprise (Microsoft 按,2008年) 的架構設計人員中取得。 根據在義大利,Dino 是經常在世界各地的產業活動演講者簡報。 您可以加入在他部落格 weblogs.asp。 網路/despos.