2

Some confusion about MVP and MVVM

Before ask this question, I have read a lof of article about MVP and MVVM. (eg: http://martinfowler.com/eaaDev/uiArchs.html)

But when starting a rich client application development, I still have some confusion about these two patterns.

  1. What is the Model's meaning in the MVP and MVVM?

For instance, a rich client application will use local database and remote service at the same time.

In the business layer, there are two kinds of object!

Domain object which is read from my local database.

Session object which used for keeping persistent connection (eg: watch online user asynchronously)

The Domain object are Model that is right, but do I need a special model layer to manager online user (or char message) and then mapping to ViewModel? or set these data to ViewModel directly? (Is the mapping redundant? Since one ViewModel can have several views, ViewModel is very similar with Model)

  1. In MVVM, the ViewModel can be persisted to database?

For instance, imagine a chat application, even though you open the application in offline enviorment, you should still be able to see the recent messages in the chat window.

But these recent message are in ViewModel, should we persist ViewModel to database? (They are exactly Model or ViewModel?)

  1. Is MVP better than MVVM?

In MVP, There is only one "Model layer", so I can manager and store domian object and session object in this Model Layer. All view special states are in the View which won't be persisted. Presenter will control view state and synchronize data between Model and View.

In MVVM, There are two "Model layer" (Model and ViewModel), view state and a copy of Model are stored in ViewModel. So the copy of the Model are redundant?

  1. Should Presenter or ViewModel be able to see Data transfer object (DTO) for special external service?

Or just place external service call in separated model layer?

Very thanks :-)

Adrian Thompson Phillips
  • 6,278
  • 6
  • 34
  • 61
chansey
  • 541
  • 4
  • 10

3 Answers3

1
  1. MVC originally defined the Model as a "digital model that exists in the computer" as opposed to "the human user's mental model". It is therefore a very vague notion that can cover pretty much any reality you want, although the countless MV* implementations that appeared since have introduced more opinionated definitions.

    A traditional conflict in schools of thought is whether the Model in MVC/P should be a domain object or just a reflection of what's presented to the user. MVVM gives a clear answer to that (see 2. and 3.)

  2. No, because the ViewModel is just a transient in-memory structure standing for what's displayed on a screen. If there's anything to persist in the MV* pattern, it's the Model.

  3. MVVM exists in an attempt to separate the business model (M) from the data and behavior of the UI screen (VM), a distinction that is not clearly stated by MVP. There aren't two copies of the model in MVVM, M and VM are not redundant because they don't always have the same data and they never have the same behavior.

    For instance, a UserCredentials Model object will contain Login and Password fields while the corresponding UserCredentialsViewModel might contain an additional ConfirmPassword field and a VerifyPasswordMatchesConfirm() method, because that's what is displayed to the user.

    Another major difference is the presence of event-based data binding in MVVM which doesn't exist in MVP. One consequence is that you'll often see the MVVM pattern used on the client side where there's technology allowing such binding (Javascript, WPF) while MVP is mostly used on the server side (chiefly ASP.NET). MVP is not better than MVVM, they just fit in different ecosystems.

  4. Presenter and ViewModel are, as their names imply, UI beasts. They might be able to see DTO's resulting from a remote service call if you pass them the DTO's, but they shouldn't call the remote service because it's not a presentation object's responsibility to do so. You should do that in a separate infrastructure service.

guillaume31
  • 12,725
  • 28
  • 43
  • Thanks for replay. About (4.) If ViewModel be able to see DTO's resulting from a remote service call, it will store these DTO in the ViewModel directly..... This means : (1) ViewModel will convert DTO to ViewModel's type (2) These data won't be persisted (as you said ViewModel is just a transient in-memory, that's not good....) In my opinion, we should do that in a separate model layer service instead of infrastructure service, because infrastructure always stateless. – chansey Aug 07 '15 at 14:27
  • Then we will do two bindings: (1) bind "model layer service's data"(eg: online user list) to Viewmodel (2) bind Viewmodel to view. Is this right? – chansey Aug 07 '15 at 14:29
  • I think it should be in an infrastructure service because calling a remote API requires knowing low-level technical details about the protocol, remote address, etc. Also, you don't need to be stateful here. Stateful means you remember stuff between two calls from a same client. – guillaume31 Aug 07 '15 at 14:47
  • Binding refers to a special technique that updates something automatically when its data source changes. You normally don't bind a service to a view model, you just pass some data returned by the service to the view model, through the VM's constructor or other methods. – guillaume31 Aug 07 '15 at 14:50
  • I said "stateful" means a service it will keep a connection for a long time and receive event from remote server. (eg: UserJoin UserLeave, they are DTOs) When I recive a UserJoinEvent, I will convert UserJoinEvent object to User entity object and store User object in a collection (List OnlineUsers). The question is: who owns this collection? ViewModel? or Model? or Stateful Service? – chansey Aug 07 '15 at 15:01
  • If the screen displays a list of users, the ViewModel will contain a list of `UserViewModel`s, not `User`s. The Model (whatever it is) owns the collection of `Users`. – guillaume31 Aug 07 '15 at 15:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/85445/discussion-between-chansey-and-guillaume31). – chansey Aug 07 '15 at 16:11
0

In all of these cases I wouldn't think of any of the letters of these MV* patterns as layers. Think of them more as separated concerns.

To do any MV* pattern well I would recommend mapping between your Model and View Model. Primarily because your Model's concern is to represent that entity within the context of your business domain, where-as your View Model's concern is to display/translate the relevant information from one or many Models onto the View. If you see these as a one-to-one relationship, or you come across anyone trying to use Models directly in the View, they're doing it wrong. Especially if the Model is derived from the database by means of something like an ORM (EF/NHibernate). In the worst cases, people use no mapping and use their ORM generated entities (even if they try to kid themselves by using code-first) in their Views. Ideally these layers should be able to change independently.

To answer your questions:

  1. In both cases the Model is the Domain Model, a collection of entities, value objects and services that represent concepts in your business domain.
  2. This sounds a bit like CQRS, where View Models on a shared View can be cached. In general though, you don't persist View Models.
  3. They are different patterns built around a similar theme, they each have their own strengths and weaknesses. But essentially all the MV* patterns are trying to separate the View, from the Model, from the business rules and UI routing. One real world example of where this might help is if you work for a company that has developers and copy writers, the copy writers can work on the UI files without disturbing the developers and vice-versa.
  4. Personally I place my interactions with external web services in their own projects in the infrastructure layer (using an onion architecture)
Adrian Thompson Phillips
  • 6,278
  • 6
  • 34
  • 61
0

Here's my $0.02:

1) The 'Model' is an abstract concept. For me, the Model is whatever you need to get the work done. For example, in MVP the Presenter might have a dependency on its view and two services. Here, the two services represent the Model. In another case it might be a single repository or just a database connection.

2) The ViewModel should not be persisted. The ViewModel will interact with persistable things via the Model.

3) See my answer to this question. It's not a question of which is better. It's a question of which tool is the right one for the job.

4) I think it's OK for Presenter/ViewModels to work with domain objects. I prefer to keep Views protected from knowledge of domain objects by using primitives but this is only a preference.

Community
  • 1
  • 1
David Osborne
  • 6,052
  • 1
  • 19
  • 32
  • Thanks for replay. Since this comment is too long, I will divide to several comments.... – chansey Aug 07 '15 at 10:01
  • You said "in MVP the Presenter might have a dependency on its view and two services. Here, the two services represent the Model. " These means session object(online user list and chat message) will represent the Model, is right? (eg: ChatService) – chansey Aug 07 '15 at 10:02
  • But What is the Service's meaning and where session object store in? (A) Service means an external service getway (stateless). Therefore the session object will stored in View (MVP) and ViewModel(MVVM). (B) Service means an internal service? (stateful) Therefore the session object will stored in Service! (eg: ChatSessionManager) – chansey Aug 07 '15 at 10:02
  • In case (A), it's OK for simple application, but more complex application maybe need an internal service which need keep some session state and interact with other components/service in system. – chansey Aug 07 '15 at 10:02
  • In case (B), since Service is stateful and that is Model, so We can bind Service's session state to View directly! (eg: ChatSessionManager ChatWindowView) The workflow is: Presenter -> internal service -> external service -> internal service save state from external service -> Presenter observe internal service state and update view! – chansey Aug 07 '15 at 10:02
  • In this case, since session(entity or DTO) are store in internal service, ViewModel seems redundant... – chansey Aug 07 '15 at 10:03
  • The ViewModel cannot be redundant. The key objective of these separated presentation patterns is to facilitate automated testing. With this in mind, the ViewModel is the main target of these tests. – David Osborne Aug 07 '15 at 10:24