When I'm processing business logic in an MVVM app. Should I do this on the Model or the ViewModel?
For example, if I want to re-calculate costs after an Asset has been re-valued, should I operate on the Model?
Is there an advantage in doing this on the ViewModel instead?
What happens if I have a list of ViewModels, but I want to translate that into a list of Models so I can do some processing? I could expose the Model as a property of the ViewModel (and use that to build the list of Models). But that means that the View will be able to access properties of the original Model
My suggestion is to put logic in a service layer instead.
This is a middle layer between view model and model (which, in a real object oriented paradigm, should only contains properties).
So the correct life circle may be:
View model -> service -> model handling.
This allows also to reuse business logic code through others view model if needed
The Model's purpose is to represent (or model) your business domain. Therefore, business logic by definition goes in the Model, not the ViewModel.
The job of the ViewModel is to expose properties and fields of the Model, and prepare them for consumption by the View.
For instance, picture a banking application. The Model may represent an account. Perhaps the Model has an account balance. The job of the Model may be to track the balance and make sure certain invariants are maintained (such as not allowing a withdrawal that is larger than the balance). The job of the ViewModel may be to turn the balance into a string that is used as a binding in the View.
You want to keep as much logic out of the ViewModel as possible to keep your code reusable and loosely coupled.
Use the model if you are building a web app; and one level bellow the model i.e. the domain level if you are building a LAN/desk app.
Your problem - re-calculate costs after an asset has been re-valued - might not just be a user interface issue. A back-end application might want to do the same (for example, for automatically importing data). And then you have a choice of either duplicating business logic or rewiring to existing one.
Nothing wrong with using the same model for the back-end too. But models -especially disconnected ones- tend to be large data structures because they need to bring with them all data from reference tables (unless you want to do round trips to server and sacrifice your GUI experience). And that might affect performance if model is used.
if you model contain required data for calculation you can use model.if model does not contain the data means create view-model and get data to do the calculation.(With respect to Business logic )
if you want to pass this data to view create View Model It improves code re-use opportunities
Related
A colleague of mine doesn't want to bind from the View directly to the Model. For example, in the Model, he has a ObservableCollection and in the View he wants to use it. Instead of directly using it like I would do it (e.g. {Binding Model.Collection} he has another ObservableCollection in the ViewModel which has exactly the same data as the ObservableCollection in the Model. He is synchronizing both ObservableCollections with each other through events.
What are the benefits of his approach? I, personally, disapprove of his approach because it just adds duplicate code and since you have to synchronize the ObservableCollections yourself it's also more error prone. My colleague says he wants to do it this way because then he can change the Model without changing the View.
EDIT:
Some highly upvoted answers [1][2][3] support my in my thinking that it's really okay to bind directly to the Model.
It all comes down to code separation and reusability. Ideally, the View should be completely separated from the Model. If the View doesn’t rely on a specific implementation of the Model, then it can be reused with a different model to present some other data.
So, suppose you have a AlbumView and your current Model is Album, but in future you have decided to also add Movie or Book to you library. you could still use the same AlbumViewo display your movie and book objects. Furthermore, if you want to create a new project that has something to do with albums, you could simply reuse your Album class, because it’s not dependent on any view. That’s the strength of MVVM or MVC.
So for me, I would say, that your colleague is right, because Model naturally reflect the Data Access Layer Entity, where it will be stored and handled. In addition to that, Model may have more properties related to Access data layer such as created indexing. While you ViewModel is only related to the view and the presentation logic of your application. It only reflect what the user is going to see.
I would say using an ObservableCollection in the Model layer is wrong. By adding that you are basically saying "Model object stores data and notifies when it changes".
The role of the ViewModel is to manipulate the Model and provide an interface to the View for presenting the Model.
I believe your colleague is right because he is enforcing separation of concerns such that manipulating the Model should not impact the View.
first of all, please forgive me if I get the terminology wrong. Terminology is important, but similar concepts are often expressed with different terms.
Let's say I have two, not well defined, "entities" in my presentation layer that must use the same data retrieved from the Service layer. What does entities should be?
Should these entities be both presenters of MVPs? If so, does it make sense to create two MVP triads that handles somehow the same data (but of course in a different way)?
Is it perhaps better to have one presenter and multiple views?
Or maybe it means that the Model is too bloated and it should be split into different models?
Although I am sure there is a design issue somewhere in our code, I noticed that we have several classes, that cannot even be defined as presenters, using independently the same data from the service layer and this bothers me a lot.
In MVP, the Presenter is tighly coupled to each View (since it controls the behaviour of the View). That means if you have multiple Views that differ substantially, then you need to have also multiple Presenters.
But neither the View nor the Presenter hold any data. The Model is the representation of the current state of the data in the application.
So if the data you fetch from the service layer is handled in the same way for both cases (but just presented differently), then you should have one Model which is referenced by both Presenters.
But if what you fetch is just some kind of "raw" data which gets processed in a very different way, then you probably should also create an own Model for each Presenter/View. The model can reference the fetched data which can be held somewhere in the Service layer or a higher level model object.
So I have been searching for a while and all my searches on the model portion are just confusing me.
I have been seeing many examples where the view model has a direct reference to the model and then sets the model's member variables. However isn't the model supposed to be a business object so that the business layer can do calculations with that data?
So...
1) Should I share the model between both UI and the Business layer so both are referencing the exact same objects (shouldn't each layer "hide" their contents from each other in which case this wouldnt be the best).
http://blog.trivadis.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-01-50/1856.distributed_5F00_domain.png
2) Or should the model be in the business layer. Then the UI makes calls from the view model using provided business interfaces to access model info? This way the model itself is hidden from the UI. Similar to option 1's image except there would be some interface accessing the models and services.
3) Or UI does have the model. BUT I can see many occasions where the business layer would need this information resulting in multiple models which look relatively the exact same are made. Imagine that the entire picture below resides in the UI. Then there is a business layer below the model which the model accesses.
http://rarcher.azurewebsites.net/Images/mvvm00.png
The View never has direct access to the Model. The View is connected to the ViewModel via its DataContext.
The ViewModel has direct access to the Model and is able to recover values from the Model and set values into it as well as call methods so that actions occur. But the ViewModel does not have direct access to the View, there could 0, 1 or many View instances all looking at the same ViewModel and it would never know.
The Model does not know about the existence of the ViewModel or View. Therefore you could reuse the Model class in a different project without any dependency on WPF or even a user interface.
How you attach the Model to the ViewModel is up to you. You could pass a reference to the Model into the constructor of the ViewModel. Or provide a separate method or property that is called after the ViewModel is constructed.
For complete separation you would expose the same list of properties on the ViewModel as are present on the Model itself (or just the subset actually needed). The ViewModel can hook into the PropertyChanged event of the INotifyPropertyChanged interface that should be exposed from the Model. As it sees changes it can pass the change onto any watching View via its own properties and its own implementation of the INotifyPropertyChanged interface.
As #Phil Wright states in his answer, the Model should have no knowledge of the ViewModel or the View, so you are free to reuse your Models between different layers. In my experience, Models are generally simple POCOs with no dependencies on other layers.
Whether you reuse your Models between your layers is up to you. If you're using an ORM such as Entity Framework, your Models might be your entity classes. Your business layer might decide to use these entity classes, or you may want to abstract them or aggregate them or do something else with them. At the end of the day what goes in your Models is driven by what you want to store in them and how you want to use them, and SO can't really provide guidance on that because the question is so open-ended.
As far as WPF and MVVM are concerned, I like to think of the ViewModel as being an aggregator of sorts for one or more Models. You generally pass the Model(s) to the ViewModel somehow (through its constructor or whatever): the ViewModel then provides properties and commands that are used by the View (via binding) in order to read and/or change the state of the ViewModel. At some later point, the ViewModel may need to change the state of the Models that it was supplied with, to reflect the changes initiated by the View.
You may find that the Models needed by your business layer are slightly different to the Models used by your ViewModels, and unfortunately you can end-up writing a lot of very similar-looking Model code when this happens. In such cases, Model interfaces may help: there's nothing to say that the Models used by a ViewModel have to be concrete classes. So you could have a single "sort of complex" Model that has all the properties needed by both your ViewModels and your business layer, then expose that Model through two different interfaces (one for each layer) so that properties irrelevant to a particular layer are not visible to it (if that makes sense!).
My model consists of a single main object that the user can add various other objects too. The added objects are stored in List<object> contained within the main object and it's associated child objects.
So if the project is a house. The user can add a number of Room objects to the house which are stored in List<Room> RoomList. Then each Room can have a number of Furnishings added again stored in each Room List<Furnishing> FurnishingsList
The question is how to implement this in the MVVM approach? When the user adds a new object do i add it to the ObservableCollection in the ViewModel so the view is updated and at the same time add it to the model which is hooked into the VM? Or do i store it in the VM until a save or commit commmand and then pass it to the Model?
In my example i have various editors (each is a user control). So the user can edit the house at a high level, using one editor to add, edit and remove rooms from the house. And, at a lower level, using a different editor to edit each room, adding and removing Furnishings.
So when the user 'Edits' a room say. I produce an EditRoomModelView containing said Room. The user adds, edits and otherwise manipulates the furnishings in that room.
At each command is it best to sync the data in the Model and the ModelViee as above. Or do i shove the changes straight into the Model and have the ViewModel provide only getters on the injected Model properties. This way however adding objects to the Model Lists does not update the view. i would really have to add the data to both the ModelView and the Model at the same time so everything is at the same state.
Appologies for rambling, struggling to find a nice approach to this, anyone uderstand what i'm getting at?
I'm not sure there's a single, good answer. It sounds as though you're debating as to how to maintain coherence - do you have a simple pass-through scheme from the presentation layer, or do you interpose on user requests and have logic in there.
If that is, in fact, the question, there are various factors at play. Do you prefer to do validation in the presentation layer? How complex is the application and how scaleable does it need to be? Do your view models need to be accessed in multiple places?
So, with all that in mind, I can tell you how I personally prefer approaching this problem (specifically, the issue of adding that you mention). I typically like to create view models that describe user concerns with generics such as EditItemViewModel<T> or ListViewModel<T>. So, in the GUI, there would be some kind of listbox of rooms bound to a ListViewModel<Room>. This VM would obviously expose an observable collection, but also commands for Add, Delete, Edit.
So, from my perspective, the presentation layer, view-modelly stuff that this VM is going to do is route requests for other GUI concerns. If you click "Add" to add a room, this VM is responsible for initiating a request, via a command, for whatever screen/window/whatever is necessary for room adding, which will have its own VM. This VM, upon receiving an add request, will pass the generated data transfer object down to the domain where validation will occur and whatever domain operations are necessary. I usually handle this via a service layer. Now, if the domain operation was successful, the service layer will raise some kind of even or callback to let the list VM know that there is a change. When that happens, the list VM re-queries its service and updates its observable collection accordingly. Now, your GUI is consistent with the domain across the board.
The reason I favor this type of layered approach is that all of the business logic occurs in a place 'below' the GUI, and the GUI need not concern itself with this occurrence. Conceptually, GUI just says "here, domain layer, user wants to add this - do all that, and let any interested GUI components know when you're done so that they can refresh themselves".
What I'm describing here will naturally incur some overhead as compared to a simple, pass-through scheme or a scheme in which the VMs just re-expose properties on some model object. But, personally, I think the advantage gained from a decoupling perspective is worth it, especially as you scale up the application. It gives you the ability to fundamentally alter the domain model's internal interactions without changing the presentation layer code a lick.
First: View is a mirror of your DataModel, so always add first to the Model and only after think if it push on Vm or on View.
Second: ViewModel is a bridge that connects your Model with View, but doesn't mean that it has to be structured in a same way Model was made. If you want to show to the user all child collections, you have to expose them like a properties and construct their parent-child relationship internaly in VM or in VM have just "raw" collections and have effective relationship between them in DataModel.
From the application you describe it sounds like your view-model layer does not modify or shape your model significantly. So, I would make the various view-model property setters / getters simple adapters on the wrapped model objects. That way your model will be updated immediately when the view model changes.
However ... if you need to provide 'cancel' functionality, i.e. the user opens a modal form for editing some view model, but then cancels rather than OK's the edit, this simple approach will not work.
The timing of when you commit to the model layer rarely makes much difference because this is typically not a time consuming process. What is more significant is when the model state is persisted. This is often triggered by the explicit invocation of a save command which send the model to a persistence service (file / cloud etc ...)
Should the model just be data structures? Where do the services (data access, business logic) sit in MVC?
Lets assume I have a view that shows a list of customer orders. I have a controller class that handles the clicks on the view controls (buttons, etc).
Should the controller kick off the data access code? Think button click, reload order query. Or should this go through the model layer at all?
Any example code would be great!
Generally I implement MVC as follows:
View - Receives data from the controller and generates output. Generally only display logic should appear here. For example, if you wanted to take an existing site and produce a mobile/iPhone version of it, you should be able to do that just by replacing the views (assuming you wanted the same functionality).
Model - Wrap access to data in models. In my apps, all SQL lives in the Model layer, no direct data access is allowed in the Views or Controllers. As Elie points out in another answer, the idea here is to (at least partially) insulate your Controllers/Views from changes in database structure. Models are also a good place to implement logic such as updating a "last modified" date whenever a field changes. If a major data source for your application is an external web service, consider whether wrapping that in a model class.
Controllers - Used to glue Models and Views together. Implement application logic here, validate forms, transfer data from models to views, etc.
For example, in my apps, when a page is requested, the controller will fetch whatever data is required from the models, and pass it to a view to generate the page the user sees. If that page was a form, the form may then be submitted, the controller handles validation, creates the necessary model and uses it to save the data.
If you follow this method, Models end up being quite generic and reusable. Your controllers are of a manageable size and complexity because data access and display has been removed to Models and Views respectively, and your views should be simple enough that a designer (with a little training) could comprehend them.
I wouldn't put Data Access Code in the Controller.
To build on what has already been said, it's important to think of layering WITHIN the layers. For example, you will likely have multiple layers within the Model itself - a Data Access Layer which performs any ORM and Database access and a more abstract layer which represents the Business Objects (without any knowledge of HOW to access their data).
This will allow you to test the components of your system more easily, as it supports mocking.
I like to keep the "contracts", or interfaces, for model persistence or service access in the domain (model) layer. I put implementations of data access or service calls in another layer.
The controllers are instantiated with constructors that take interfaces for the services, e.g. ISomeService, as parameters. The controllers themselves don't know how the service layers are implemented, but they can access them. Then I can easily substitute SqlSomeService or InMemorySomeService.
I've also been fairly happy with a concrete service implementation that takes a domain (model) layer repository as a parameter to its constructor.. For example: ICatalogRepository with SqlServerCatalogRepositry : ICatalogRepository is handed to CatalogService(ICatalogRepository, ISomeOtherDependency).
This kind of separation is easier with dependency injection frameworks.
The View would relay what should happen on a click in the UI to the Control layer, which would contain ALL business logic, and would in turn call the Model layer which would only make database calls. Only the model layer should be making database calls, or you will defeat the purpose of the MVC design pattern.
Think about it this way. Let's say you change your database. You would want to limit the amount of code change required, and keep all those changes together without affecting other pieces of your application. So by keeping all data access in the Model layer, even the simple calls, you limit any changes required to the Model layer. If you were to bypass the Model layer for any reason, you would now have to extend any changes needed to any code that knows about the database, making such maintenance more complex than it should be.