11

我在哪裏工作,我們已經多次討論這個問題,並正在尋求一個完整的檢查。下面是問題:Business Objects應該是數據容器(更像是DTO),還是應該包含可以在該對象上執行某些功能的邏輯。Business Objects - 容器還是功能?

示例 - 如果客戶對象包含一些常用屬性(名稱,Id等),並且該客戶對象還包含函數(Save,Calc等)?

一條推理說,將對象與功能(單一責任主體)分開,並將功能放入業務邏輯層或對象中。

另一種推理說,不,如果我有一個客戶對象,我只想調用Customer.Save並完成它。爲什麼我需要知道如何保存客戶,如果我消費對象?

我們最近的兩個項目已經將功能與對象分開了,但是關於新項目的爭論再次提出。哪個更有意義?

編輯

這些結果非常相似,我們的辯論。對一方或另一方投一票將徹底改變方向。還有其他人想要加2美分嗎?

EDIT

Eventhough答案採樣小,似乎大多數相信在業務對象的功能是可接受的,只要它是簡單的,但持久性最好放在一個單獨的類/層。我們會試試這個。感謝大家的輸入......

回答

10

對象一起是狀態和行爲。如果一個對象有明顯的行爲(例如,從他們的出生日期計算一個人的年齡,或者爲一張發票計算一個總稅額),通過所有手段添加它。無非是DTO的業務對象被稱爲「貧血域模型」。我不認爲這是一個設計要求。

持久性是一種特殊的行爲。我稱之爲「明智的」是商業行爲。一個業務對象不需要知道它是持久的。我會說,一個DAO可以保持持久性與業務行爲分開。我不把「保存」放在「明智」的範疇。

+0

只是澄清......你的想法是計算和其他簡單的函數應該駐留在對象中,但持久性(即.db事務)應駐留在別處。我有這個權利嗎? – Walter 2009-11-25 13:31:48

+0

是的,這就是我要說的。當然,這不是唯一的方法。有些人喜歡有物體堅持自己。我通常不會。 – duffymo 2009-11-25 20:37:58

+0

我們一直在討論業務對象或None中的所有功能。這是我們從未想到的一種可能的妥協。 – Walter 2009-11-30 23:04:46

2

我認爲讓業務對象知道如何「處理」自己更有意義,然後必須將這種負擔放在系統的其他地方。在您的示例中,處理如何「保存」客戶數據的最合理的地方對於我而言是在Customer對象中。

這可能是因爲我認爲數據庫是「數據容器」,所以我支持「業務對象」是保護數據容器免受直接訪問的較高級別,並強制執行標準的「業務規則」關於如何訪問/操縱數據。

+5

我會說,而不是客戶對象應該知道如何創建一個「可保存」的表示(例如,哪些屬性需要保存並稍後恢復); *實際上*堅持該表示(例如在數據庫中)的細節應該完全傳遞給另一個類。 – 2009-11-30 16:23:06

+0

由於BO可以被一系列使用不同語言和數據存儲的系統使用,所以我很樂意看到這些工作。 – 2010-07-14 18:59:16

9

業務對象 CAN可以有業務功能

持久性不是業務功能,但是技術實現。

長話短說:

  1. 保存/更新/刪除/查找等等 - 在一個持久層保持從業務對象了。
  2. CalculateSalary,ApplyDiscount等是業務相關的方法,可以是:
    1. 業務的方法的對象(所以BO是實體的自包含表示)或;
    2. 單獨的服務實現特定功能(所以BO更像DTOs)。

至於點2
我應該提到的是,辦法2.1傾向於使BO的過於臃腫和違反SRP。而2.2引入了更多的維護複雜性

我通常餘額在讓我把2.1和2.2之間的相關數據爲業務對象瑣碎的事情,並創建服務稍微複雜scenarious(如果有超過4行代碼 - 使它服務)。

這將Business Objects的範例轉變爲更多的數據傳輸對象。

但是,這一切都使項目更容易開發,測試和維護。

+0

我用所需的東西來分割2.1和2.2。需要業務對象的功能或僅具有相同功能組的相關對象的功能 - 進入對象(CalculateAge on Person)。使用更多不相關對象的過程(CalculateDiscount考慮到居住地,交付等)是一項單獨的服務,很可能甚至是單獨的模塊/組件。非常複雜的邏輯也是一個單獨的類(支付計劃中的PaymentPlanCalculator),但是使用C#作爲擴展方法公開(在類中使用,但技術上不在其上)。 – TomTom 2010-05-14 10:22:59

+0

感謝您讓我閱讀SRP。這難道不會使課程數量膨脹,讓維修變得更加困難嗎? 我知道,應該是一個全新的問題。 – 2010-07-14 18:57:40

1

業務對象應該是關於封裝由該對象建模的業務實體的數據和關聯行爲。可以這樣想:面向對象編程的主要原則之一是將數據和關聯的行爲封裝在該數據上。

持久性不是建模對象的行爲。如果業務對象是持久性的,那麼我發現開發更順利。如果業務對象與底層管道沒有明確關聯,開發新代碼和單元測試新代碼發生得更快,更平滑。這是因爲我可以嘲笑這些方面,並忘記必須通過hoops來訪問數據庫等。我的單元測試將更快地執行(如果每次構建都有數千個自動化測試,那麼將會更加快速),而且我將減少壓力,因爲我不會因爲數據庫連接問題而導致測試失敗(如果您經常脫機或遠程工作,並且無法始終訪問數據庫,那麼哦,順便提一下,這些方面(數據庫連接等)應該在其他地方進行測試!)。

推理的另一種說法是,不,如果我有一個客戶對象,我只想撥打Customer.Save並完成它。爲什麼我需要知道如何保存客戶,如果我消費對象?

知道Customer有一個Save方法已經知道如何保存客戶對象。通過在業務對象中嵌入該邏輯,您並未避免這個問題。相反,您已使您的代碼庫更緊密地耦合,因此難以維護和測試。推卸堅持對象給別人的責任。

+0

似乎這裏的大部分答案都採取了非常單方面的做法。只有一種語言,因此您可以將「代碼」對象與業務對象混淆。我是否天真地採取更廣泛的觀點,我的業務對象的方法沒有在BO本身的設計中實現,而是在每個尋求使用BO的解決方案中實現? – 2010-07-14 19:02:05

+0

@Stephanie Page:它與語言關係較少,更多與潛在模式有關。當對象行爲的焦點從域到環境交叉時,問題就來了。如果對象被保存到數據庫中,我們是否需要在每個域/業務對象中包含數據庫邏輯,即連接字符串和字段/列映射或SQL語句?除非將DB邏輯分解到其自己的層中,否則這種方法很快變得難以管理。很少有語言可以處理這種情況,並防止它成爲臃腫或冗餘代碼的來源。 – 2010-07-14 19:40:57

+1

我喜歡這樣:從域名到環境的交叉......這是一個很好的比喻。 – 2010-07-16 14:52:45

3

無論平臺或語言如何,答案都是一樣的。這個問題的關鍵在於一個對象是否應該能夠成爲自主或者是否更好地將任何給定的行爲散佈在具有更多重點責任的對象中。

對於每個班級,答案可能不同。我們最終得到一個光譜,我們可以根據密度責任密度來安排課程。

      (Level of responsibility for behavior) 
     Autonomy - - - - - - - - - - - - - - - - - - - Dependence 
     High 
    C  - <<GOD object>>       <<Spaghetti code>> 
    l  - 
    a  - 
    s  -          
    s  -     
     -       
    s  - 
    i  - 
    z  - 
    e  - <<Template>>        <<Framework>> 
     low 

假設你贊成讓班級自己執行所有行爲,或者儘可能多地執行所有行爲。從這張圖的左邊開始,當你讓自己的班級變得更加獨立時,班級的規模將會增長,除非你不斷重構它以使其更具通用性。這導致模板。如果沒有完成重構,那麼這個類的變化就會變得更像「god-like」,因爲如果它需要一些行爲,它就有了一個方法。領域和方法的數量不斷增長,很快就變得難以管理和不可避免。由於課程已經做得如此之多,編程人員寧可添加到怪物中,也不願意將它分開並剪掉Gordian結。

圖的右側有很大程度上依賴於其他類的類。如果依賴關係很高但個人分類很小,那是框架的標誌;每個類沒有太大的作用,並且需要大量的依賴類來完成某些功能。另一方面,具有大量代碼的高度依賴類也是該類充滿意大利麪條的標誌。

這個問題的關鍵是要確定你在圖上感覺更舒適的地方。無論如何,除非採用某種組織原則,個別課程最終將分散在圖表上,這就是您如何實現模板框架的結果。

我剛纔寫到,我會說班級規模和組織程度之間存在關聯。羅伯特C.馬丁(或「鮑勃叔叔」)在其關於Design Principles and Design Patterns的非常徹底的論文中涵蓋了與包依賴關係類似的理由。 JDepend是第26頁圖表背後思想的一個實現,並補充了static analysis tools,如CheckstylePMD

+1

+1細分。這將增加我們的辯論。謝謝。 – Walter 2009-11-30 23:37:47

+0

圖表工作需要多長時間?非常好的答案...在網站上最好的Q/A之一。 – 2010-07-14 19:04:30

+0

@Stephanie:它花了很多反覆試驗。這個答案是我在Meta中爲Markdown提供表格支持的功能請求的原因之一。 http://meta.stackexchange.com/questions/16356/why-cant-table-markup-elements-be-used/29368#29368 – 2010-07-15 13:32:42

0

業務對象,因爲它們被命名,顯然應該配置自己的業務邏輯,即業務邏輯在服務層中的域之間的動態。另一方面,BO可以作爲數據容器(DTO?)的組成和方法嗎?意味着BO是純粹的函數?這可以避免BO和DTO之間的所有轉換。

-1

在MVC架構中,

我們可以說模型包含業務對象。

2

我們已經使用了Rocky Lhotka的CSLA框架多年,並且喜歡它的設計方式。在該框架中,所有功能都包含在對象中。雖然我可以看到將邏輯分離出來的價值,但我認爲我們不會很快擺脫這種理念。

+0

優秀點。我也在一些項目上使用過CSLA。我從來沒有想過把它列入我們的辯論。 – Walter 2010-11-14 13:54:20