2015-02-06 29 views
3

所以我一直在尋找一段時間,所有我在模型部分的搜索只是混淆了我。與模型和業務層連接mvvm淹沒

我已經看到很多例子,其中視圖模型直接引用模型,然後設置模型的成員變量。但是,不是模型應該是業務對象,以便業務層可以使用該數據進行計算嗎?

所以......

1)我應該分享兩個UI和業務層,兩者相互引用完全相同的對象(不應該每一層「皮」的內容之間的模型,其中情況下這不會是最好的)。

http://blog.trivadis.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-01-50/1856.distributed_5F00_domain.png

2),還是應該模型是在業務層。然後,UI使用提供的業務接口從視圖模型調用訪問模型信息?這樣,模型本身就從UI中隱藏起來了。類似於選項1的圖像,除了會有一些接口訪問模型和服務。

3)或UI確實有模型。但是我可以看到許多場合,業務層需要這些信息,導致多個模型看起來相對完全相同。想象一下,下面的整個圖片都在用戶界面中。然後在模型訪問的模型下面有一個業務層。 http://rarcher.azurewebsites.net/Images/mvvm00.png

回答

2

查看從來沒有直接訪問模型。該視圖通過其DataContext連接到ViewModel。

ViewModel可以直接訪問模型,並且能夠從模型中恢復值並將值設置到其中以及調用方法以便執行操作。但ViewModel沒有直接訪問視圖,可能有0個,1個或許多View實例都在查看相同的ViewModel,它永遠不會知道。

模型不知道ViewModel或View的存在。因此,您可以在不依賴於WPF甚至用戶界面的情況下在不同的項目中重用Model類。

如何將模型附加到ViewModel取決於您。您可以將對Model的引用傳遞給ViewModel的構造函數。或者提供在構建ViewModel之後調用的獨立方法或屬性。

對於完全分離,您將在ViewModel上公開與Model本身(或實際需要的子集)上存在的相同屬性列表。 ViewModel可以掛接到應該從模型公開的INotifyPropertyChanged接口的PropertyChanged事件。當它看到更改時,它可以通過它自己的屬性和它自己的INotifyPropertyChanged接口實現將更改傳遞到任何正在觀看的View上。

+0

我明白這一切。我遇到的問題是誰實際上擁有該模型,並直接由UI和業務層引用。對我來說,它聽起來像我提供的選項1是正確的。但是選項2是否可行?選項2似乎對大型項目更靈活,但我沒有看到任何示例顯示或說話選項2.謝謝。 – 2015-02-06 01:43:42

+1

技術上來說,ViewModel不是UI(看起來你對所有選項都感到困惑)。 ViewModel是表示層(n層術語),其中只包含persentation邏輯,但是與UI無關(閱讀:您可以在控制檯應用程序,Windows Store應用程序,Silverlight或MVC5 WebApp中重複使用ViewModel)。只有一層。有不同類型的模型。您的「域」模型位於域(又稱商業)層。其他模型是DataTransferObjects(跨邊界問題的業務數據的子集或組合)或ViewModels(準備要由視圖使用的數據) – Tseng 2015-02-06 08:56:51

+0

並且您獲得DAO(DataAccess對象),它們是表示持久性並屬於基礎結構的模型層。這就像服務。您擁有域服務和應用程序服務。域服務處理您的域/業務邏輯。應用程序服務特定於應用程序的類型並轉到應用程序層。即FrameNavigationService(適用於WindowsStoreApps的Prism)對導航非常具體,只能在Windows應用商店應用中使用。它不能在MVC Web應用程序中重複使用 – Tseng 2015-02-06 08:59:51

0

正如@Phil Wright在他的回答中所述,模型應該沒有關於ViewModel或視圖的知識,因此您可以在不同圖層之間重複使用模型。根據我的經驗,模型通常是簡單的POCO,與其他層沒有依賴關係。

無論你在你的圖層之間重複使用你的模型取決於你。如果您使用的是諸如實體框架之類的ORM,則您的模型可能是您的實體類。您的業​​務層可能會決定使用這些實體類,或者您可能想要抽象它們或將它們聚合在一起,或者用它們做其他事情。 在這一天結束時,模型中的內容取決於你想要存儲在內容中的內容以及你想如何使用它們,因此SO不能真正提供指導,因爲這個問題是如此開放。

就WPF和MVVM而言,我喜歡將ViewModel視爲一種或多種模型的聚合器。您通常以某種方式(通過其構造函數或其他)將模型傳遞給ViewModel:ViewModel然後提供View(通過綁定)使用的屬性和命令,以便讀取和/或更改ViewModel的狀態。稍後,ViewModel可能需要更改它所提供的模型的狀態,以反映由視圖啓動的更改。

您可能會發現業務層需要的模型與您的ViewModel使用的模型略有不同,不幸的是,當這種情況發生時,最終可能會寫出很多非常相似的Model代碼。在這種情況下,Model接口可能有所幫助:沒有什麼可以說ViewModel使用的模型必須是具體的類。因此,您可以擁有一個具有所有您的ViewModel和您的業務層所需屬性的「複雜」模型,然後通過兩個不同的接口(每個接口一個接口)公開該模型,以便與特定圖層無關的屬性不可見(如果這是有道理的!)。

+0

感謝您的回覆。 1)我開始思考,因爲每一層可能都需要他們自己的模型,這些模型可能具有相同的數據,所以最好有一個DTO,所有模型都基於它們的數據。虛擬機可能會使用與某些其他域不同的模型,但它們都可以從DTO中選擇要使用哪些成員變量以及如何驗證數據。 2)這聽起來像虛擬機正在使用的模型也可以是一個領域模型,假設其功能非常相似。 – 2015-02-07 02:56:49