2009-10-08 70 views
2

我正在開發一個更加面向對象的方法來在我正在開發的一個新系統中的ASP.NET web應用程序。一個實用的面向對象的設計問題

我有一個大多數人都會熟悉的共同結構。我有一個有多個部門的學校結構;屬於單一部門的課程;和屬於多個課程的學生。

在部門視圖我列出屬於該部門的所有課程,我想爲每門課程彙總數據,如招生,取款的次數,數量男/女等

在一個單獨的課程觀但是,我將需要實際的學生名單以及他們的詳細信息,例如他們是否註冊,通過課程,性別等。

然後顯示所有學生的詳細信息,包括其他課程的註冊信息,地址等

以前,我會有廣告在訪問層返回任何我需要在每種情況下的數據,並返回它作爲SQLDataReaderDataSet(在VB.NET中工作)。現在,我試圖在面向對象的方法中對此進行建模,我在DAL中創建對象並將它們返回到BLL。我不知道如何處理這個,雖然當我需要對象的聚合細節。例如,在部門視圖和課程列表中,我將爲每個課程彙總。我會在輕量級課程對象存儲聚合值的部門中存儲一些輕量級課程對象的集合嗎?

我想在不同的場景中需要不同的抽象層次,我不確定處理這種情況的最佳方式。我應該有一個對象模型,其中有一個存儲聚合的非常基本的課程對象,以及一個可以存儲完整細節的子對象?另外,如果有任何有用的資源可以幫助我理解如何對這些偉大的事物建模。

+0

感謝您的回覆至今 - 非常感謝。我仍然不完全相信某種特定的方法。我還沒有機會閱讀Mark Seemann的領域驅動方法,但將在稍後討論。我同意安東的觀點,並希望在分貝中進行彙總,因爲這將是最佳表現。但我不確定這些ORM是否會對性能產生不利影響? – Nick 2009-10-08 09:54:07

+0

是否有人認爲可能面向對象的方法對於這種情況並不理想,或許它增加了太多的複雜性? – Nick 2009-10-08 10:34:06

回答

4

不要過分複雜的事情,不要做不必要的工作。數據庫在數據處理方面非常完美,所以讓數據庫進行聚合。對事物的代碼方面,多了一個對象添加到您的對象模型,你會好得很:

class CourseStats 
    string Name { get; } 
    int Enrollments { get; } 
    int Withdrawals { get; } 

的SQL做的聚集是非常簡單的。但是,請確保使用ORM(認爲是NHibernate)或不太複雜的結果集映射程序(認爲是BLToolkit):您並不是真的想手動提供這些對象。

一個額外的好處是,你可以緩存兩個查詢結果(並儘快與有關課程的變化無效緩存)。

0

如果部門很少,而且每個課程的數量都很少,只需加載所有內容並讓對象完成數學運算(即部門遍歷課程列表並總結所需內容)。

另一種方法是使用一些自定義的原生SQL針對數據庫運行總和。您可以將其隱藏在DAL中。例如,DAL會返回一個虛擬課程(它不存在於數據庫中但包含總和)。

第三種方法是將這些值保留在部門對象的某個位置,並在每次更改/添加/刪除課程時更新它們。

1

這實際上是一個很大的問題,很多人都在苦苦掙扎。

據我已經能夠確定,有在這個問題上的思想至少兩所學校:

  • 與支持延遲加載的OR/M持久無知的領域對象
  • 域驅動設計和明確建模(並明確加載)聚合

Jeremy Miller有article in MSDN Magazine調查一些持久性模式。

本書Domain-Driven Design對聚合建模有很好的討論。

+0

感謝您的意見馬克,我一直在閱讀MSDN雜誌的文章,這是非常好的。在標題爲精益編程的章節中,作者談論了數據訪問策略,他在那裏說,對於報告應用程序,他只會使用SQL和數據集。 我在想,也許我的應用程序確實屬於報告類別,也許這將是這種特殊情況下的最佳方法。 – Nick 2009-10-08 18:18:36

+0

我絕對同意。報告是我將放棄分層和抽象並直接在數據庫上進行派對的極少數情況之一:) – 2009-10-08 18:55:53

0

如果您使用.NET,應該調查的一件事是LINQ to SQL。它可以讓你在你的DAL中擁有一個非常優雅的界面。 LINQ將允許您在您的BLL中製作aggregate queries,這樣可以節省管道代碼以及遍佈整個源代碼的令人討厭的SQL片段。從聚集SQL查詢的一個鏈接的例子與LINQ表示:

var averageOrderTotals = 
    customers. 
    Select(c => new { 
     c.Name, 
     AverageOrderTotal = c.Orders.Average(o => o.Total) 
    }); 

我切換我的數據庫層中的LINQ雖然我 情況下,我不使用MS SQL Server的,所以我已經代替DbLinq庫。

您想要做的最後一件事就是不得不修改您的類以適應您的數據庫訪問層,這樣做會使您的解決方案非常脆弱。