I have been reading about the difference between DTO's and Viewmodels, in which the main one is the presence of behaviors in the Viewmodels compared to DTOs which just carry data through layers, but is not clearly stated the definition for behaviors as far as I read.
Viewmodels can transform the data passed in properties from a DTO to be formatted in a certain way for a certain view and also in WPF events can be added to VM's which may enrich their purpose. So what exactly "behavior" means on this case? Thanks.
As you will have read a DTO is a "Data Transfer Object".
Loosely speaking Data is one aspect of an object, the other being Behavior'. 'Behavior is again loosely speaking simply a set of related actions(methods) and events that acts upon that Data.
So an object is a container for some data and a bunch of behaviors that are related to that data. DTOs and ViewModels are both objects but they have different purposes in life and as a result have a different emphasis on the behavior they contain.
A DTO is 'only' concerned with Transporting data between, for instance, process boundaries, application tiers or networks.
As a result DTOs often have little if any behavior because behavior is actions and actions are only useful when we want to do something with the data.
Since Transportation / serialization has a transport cost we usually just want these DTOs, to be lean and mean.
However once the DTO lands at it's destination, we'll typically want to do something with the data it contains. So we peel the data out of the DTO, thanks very much for a job well done in getting it here, and stuff it into a ViewModel so we can interact with the data in some way via behaviours (methods and events) typically via some UI.
So behaviors are things like formatting a value on edit / save, triggering a change in propertyB based on the updated value in propertyA, etc.
INotifyingPropertyChanged (INPC) interface will often be implemented on a ViewModel to help with this.
So since behavior is simply options for interacting with the data ( properties, methods, events), ViewModels have this because that's what we build views for, interacting with data. DTOs' on the other hand often / typically don't have (much) behavior because their function is transport not interaction.
Generally a DTO is what its name suggests, a simple object without any behaviour that is used to transfer data across system boundaries.
However Viewmodel purpose is seperation of concern.It is the responsibilty of view model to decouple you view from model.It can perform many operations like toggle view elements.validation run some custom logic which DTO cannot.That is your viewmodel behavior.
Related
I am developing a C# wpf mvvm application in which the Model Data is represented by hierarchies and my ViewModels have to observe Parts of the hierachies in between. I would like to come up with a design that makes the application easier to maintain when the structural hierarchies of the Model change.
Example:
The Model has a hierarchy A->B->C->D. The ViewModel wants to get change notifications of D and B. At some point another ViewModel sets A to a completly new value and all other observing ViewModels have to be notified that their respetive D and B are no longer valid.
My design idea so far:
I flatten the hierachy of the models by replacing the direct reference with an unique Identifier like GUID. When a ViewModels wants to get an instance of D it actually has to ask a Repository to get an observable Proxy of D. When a write to A occurs, the observable Proxy gets notified about it and therefore the ViewModel also gets notified. The life cycle of the obervable proxy is bound to the ViewModel thats using it, e.g. the ViewModel decides when the observable proxy will be disposed.
Is there maybe already a pattern that solves this problem in C# MVVM? I saw that Android Jetpack introduced LiveData and it looks very similar to what i am trying to do.
TLDR: Anemic Domain Model, entities that reference other entities with unique keys and messagebus is the way to go.
After studying the problem I came up with a few proven solutions.
According to DDD (Domain Driven Design): Its OK to reference other aggregates by Index but not object reference. Aggregates should only be accessed via the aggregate root and encapsulate logic and child entities inside the aggregate root. This is OOP and you end up with easy to use objects that overtime become fat filled with methods and fields because, well just look at the WPF framework UserControl when you enter 'this.' and an accordeon of fields, methods and events reveals to you. One could argue that you can use inheritance and move methods out with mediators to reduce your 5kloc OOP source files, but mediator is just procedural style programming in disguise which leads me to...
The Anemic Domain Model. Entities are just data containers without behavior (methods) and only have fields that are simple or reference other entities by keys. On top of the dumb entities are the 'services' which are just stateless collections of methods that run on the dumb entities. Every write operation by a service will trigger some kind of messaging, either a message bus or other.
The anemic domain model pattern is very popular in games industry right now, but they call it 'Data oriented Design' or DOD. DOD boils down to lots of dumb data component objects where some methods run on them with the goal to achieve easy parallelism and cache coherence. In my opinion thats just old school procedural C programming with handles and it makes sense for high performance applications.
Recently, I'm learning MVVM design pattern!
In my way, I write the database function in the model, and let the viewmodel to call the database function in the model, then the viewmodel get database data and set to the viewmodel notfiypropertychanged. This is my way that I currently use!
There are some question confused me about model,
I read many article that told me model just a contain data and not more business logic, and here is my question, if model just a data container and I need to let my viewmodel to call the database then get data and set to the model, I think this way is very strange and the viewmodel code is make heavy in it. Is anybody have another method to do it? Thank you!
The Model:
"model just a contain data and not more business logic"
A model is a class which describe an entity within your domain logic. What is a domain? Starbuck's domain is coffee beverages and employees (among others), Ford's domain is cars, assembly lines, and employees. NYTimes's domain is articles, issues, supply routes, subscribers, etc, etc.
A model contains data AND logic. You can have multiple models to describe your domain.
You can place your data calls in your model, but it's more common to have helper classes, data access layers (DAL), keeping all your database calls in one place, and not spread them around.
The ViewModel:
The viewmodel sits between your domain model and your view. It's a class which expose properties of the model and represents the state of the view. The viewmodel may only exposes a subset of all the properties in the model that the UI needs to display, but it could also add properties of its own, for example; is the user in edit mode? have changes been made that needs saving? etc. The selling point with MVVM is that the UI binds to these properties on the viewmodel which is a mechanism to keep the UI up to date with changes, and this extra layer of abstraction conveniently decouples the view to any logic in your model making it more robust for code changes in either direction and testable. There's more to say on this topic, but I'll leave it to you to read on up it.
There are many good resources and info on the MVVM pattern; from blogs Model-View-ViewModel (MVVM) Explained, to Microsoft The MVVM Pattern and here on SO.
If you prefer videos, Pluralsight have good video tutorials on the MVVM pattern
Practical MVVM and WPF MVVM In Depths. They have a free 30-day trial.
"just a data container"
Such classes that only hold data to be passed around are often called Data Transfer Objects (DTO). It's common to keep them small and return collections of these from fetch database data method calls.
I've done some research in this and also found it quite confusing. First thing I like to point out is that code-patterns are abstract. Meaning that you have loads of different way to implement it / tweak it.
What most people have told me is that in "real-life" applications you usually have layers of services.
One of these services is where you get data from a database.
The Model job (in my opinion) is to give the developer knowledge about the database data and structure. One Model to one database-tabel.
It also helps in checking if the data is correct (Format checking, Type of data and so on) before sending it to the DB.
There isn't a clear answer on how to use model. I've seen loads of different implementations, and they all have been implemented for specific tasks.
Yes it might come out that some ViewModels become heavy-loaded with code and functions to perform, but then it might not be because of the code-pattern. It can be because of poor structure in code. At my work right now I've found a ViewModel that contained over 3000 lines of code (Which is WAY to much). This could easily be seperated into atleast 3 different ViewModels and Views, but as I said, poor code structure causes problem.
One thing I recommend for you to read up on is
IoC - Inversion of Control
DoP - Dependency inversion principle
DI - Dependency Injection
Hope this helps in someway explaining your question.
I read many article that told me model just a contain data and not more business logic
A model may be represented by a service, a database access layer or a business layer so there is nothing wrong with your current approach. The business logic does belong to the model.
But sometimes people tend to refer to a "child" type as a model. For example, if your view model exposes a List<Item> property, the Item class may considered to be a model. Perhaps your confusion comes from this.
This kind of classes (Item) typically implement the INotifyPropertyChanged interface to provide change notifications and are effectively rather just "nested" view models that don't contain any business logic though.
Hope that makes sense.
I've been using MVVM for a while now with WPF. And i've learnt a lot over the course of development (going from never using it, to having a couple of applications developed in it)
However, recently I had some comments directed at the code which made me wonder if i'm doing things the right way. My current setup works (roughly) like this:
Model - Responsible for storing the data, data validation using
IDataErrorInfo and dirty tracking
ViewModel - Responsible for getting the data (from a repository like
pattern) and formatting it for a view's consumption (things like
filtering, ordering) also responsible for command handling from the
view (save, load, filter changes etc)
View - The usual UI stuff
Now it was mentioned to me that i should NEVER have business logic inside the model, and that the model should be as thin as possible, the viewmodel should be responsible for handling things such as data validation and dirty tracking.
I've seen comments and criticism on both sides of this, with people against and for putting logic in the model, What i have yet to see is any actual reasons for these sweeping statements. So id love to know if there is an actual reason i should be refactoring my setup.
Also, given that i do move the logic to the viewmodel, I can see the need for having multiple viewmodels where i currently have a single, for example:
Person - Model
PersonViewModel - Handles the dirty tracking, data validation etc
PersonsViewModel - Handles getting a collection of PersonViewModels,
filtering etc
PersonsView - The UI
This seems a little redundant, but perhaps i'm misunderstanding something. What I'm really looking for is some actual reasons for doing this one way or another, or if this is another argument like the use of code-behind in MVVM (pure opinion with little reasons etc)
High level description of MVVM:
View: User Interface
Model: Business logic and data (e.g Domain Model+Repositories, or Transaction Script+POCO entities, etc)
ViewModel: Data exposted to view in such form, that is easily consumable from view. Wikipedia's definition says: The view model is an abstraction of the view that exposes public properties and commands.
I like the Practical MVVM Manifesto (archived version) principes: Simplicity, Blendability, Designability, Testability.
This is very high level and abstract description and that's why you may find a lot of variations of MVVM. Whatever mvvm style you choose, keep in mind the responsibilities and principles and you should be ok. Try to avoid complexity. MVVM is not a silverbullet and you cannot cover all scenarios with single design pattern. One mvvm implementation may be suitable for one application but not for another. I, for example, build my mvvm architecture from scratch for each new project to ensure the best fit
When is comes to responsibilities:
Take validation as an example:
validation logic that password and repeat password inputs should be equal is clearly presentation logic and should be present in viewmodel. On the other side, there may be business rule, that password must contain at least one special character. This logic should reside in Model, however you may expose it in viewmodel to be easily consumable from view. It's a business logic, but you may need to present it somehow.
if you have application that only uses webservice to retrieve and store then your model will be probably just the data access components.
Here is couple of resources:
Wikipedia: https://en.wikipedia.org/wiki/Model_View_ViewModel.
MVVM is variation of Martin Fowler's MVP pattern, you may find it useful as well: http://martinfowler.com/eaaDev/PresentationModel.html
MSDN (Pattern and practices): https://msdn.microsoft.com/en-us/library/hh848246.aspx
I like to think of the Model layer as anything that has nothing to do with how the app is hosted (i.e. independent of WPF). It is one or more dlls that represent the business domain and the operations that need to be performed in it. If it would make sense to take theses same dlls and use them in a web application, windows service e.t.c then it is usually a sign that the split between Model and ViewModel is appropriate.
There's no simple answer to your question. The simplest answer is that the model and view model should contain the code that you should unit test. The separation between model and view model is a little less distinct. I like to keep the model as simple as possible and limit it to whatever is exchanged with the server tier. The view model should encapsulate the model, and provide any addition functionality (both business logic and abstract presentation logic) so that you can keep the presentation layer as simple as possible (declarative, in the case of WPF XAML).
I see it this way:
Model - Object that can be passed around. A Common type between different layers for communication.
ViewModel - Specifically created for Views. This should contain UI logic, for example, Data Annotations etc will go here. You might also call your web service methods here (assuming your actual business logic sits in a facade layer, or your database logic sits in a different layer/project) to populate the Views, dropdowns etc. You might end up with multiples of these per view, depending on your design.
View - UI Only.
I am not afraid to put external calls in the ViewModel
I am using MVP to structure a project in C#. I previously had a IModel interface which contained CRUD operations, but have since split it into a number of Model interfaces (e.g. INotebookModel, ICategoryModel, IItemModel etc.) which each contain CRUD operations.
Would it be better to have an overall model which has CRUD methods that delegate to the appropriate specific models (e.g. create(String type)) or just holds references to each specific model in the presenter?
If having multiple models is a bad way to do it, how can I pass down the appropriate parameters so the model objects can be created/updated? As each object requires different information.
Having different models is not a bad way to do it.
This will surely make your design more complex but certainly increase your app's maintainability.
If you're building an app that needs to be evolutionary in future upgrades, then seperate your Model into several Models. This will help you in case you want to add a different entity into your app.
Maybe your books will be assigned to persons, then you will add a IPersonModel interface and the three other interfaces (INotebookModel, ICategoryModel, IItemModel) will remain intact.
However, if your application is simple and you want to favour rapid developement just centralize your model into one big Model. But be careful, if your app gets bigger, this model gets more and more complex since it will handle nearly all the app's responsabilities and you will have to explode it into many several ones.
So seperate your responsabilities, it is one of the SOLIDs. You can go further and take a look at this: http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
When using simple DTOs in various scenarios I have frequently run into the same kind of problem and I always wondered whether there's a better way to deal with it.
The thing is, I have a business object, e.g. Asset which has a bunch of properties, child objects and calculated fields, some of them expensive to calculate in sense of time, some of them huge in sense of data amonut. I need to use a different flavor of this object in various screens in the UI, e.g.
in a tree where there is a hierarchy displayed and I don't need much more than the display name
in a grid where I'm showing just a couple of properties
in a detail pane where there's a big subset of available information, but still some of it (like mapped objects) is shown only on demand
To be able to achieve optimal performance with this scenario, I have always created different DTOs for each context, only containing the subset of information which is actually used in that context. While being a resource-optimal solution, this leads to couple of problems :
I have a class explosion with huge number of DTO classes
I have quite a hard time coming up with different names for the same thing like AssetDtoForGridInTheOverviewScreenInTheUpperPaneAboveTheSplitter, not to mention maintaining them later
I am frequently repeating myself in the transformation methods, because there are properties that are used by most of the DTOs but not by all of them (therefore I can't put them into any superclass and reuse the transformation logic)
The technology I'm using is ASP.NET SOAP WebServices and C# 3.5, but I think somehow this could be a language-agnostic problem. Any ideas are welcome..
This is a known problem with DTOs. It's described in this otherwise mediocre articule on MSDN. To paraphrase: DTO is the most versatile n-tier data access pattern, but it also requires most work.
You can address some of your issues with mapping by using convention-based mapping, such as AutoMapper.
When it comes to class explosion, could it be that you are using too flat data structures?
This can be difficult to tell because DTOs naturally include a great deal of semantic repetition that turns out to not be logical repetition at all. For example, even if you have semantically similar types, if one is a ViewModel and the other is a Domain Object, they may share semantic structure, but have vastly different responsibilities.
If, on the other hand, you have a lot of repetition in the same application layer (e.g. UI), you may be violating the DRY principle. In this case, it may often help to encapsulate related data in what starts out as a flat data structure into a separate class. In most UI frameworks I'm aware of, you can still databind a flat display to a hierarchically structured class.
The problem of class explosion is inherent to the DTO approach, there probably isn't much you can do about that. Be careful not to mix your view-model with your DTO model. Your DTO's should only be used to get the data from your data tier to your front end and not for presentation.
With the advent of .NET 3.5 you can choose to implement some basic, more coarse grained DTO's and replace your ViewModel with an anonymous type which you can dynamically create off your DTO's. I found this to be avery flexible solution.
Regarding your naming conventions, it is probably useful to group your DTO's into scenarios and put them in a corresponding namespace. For example Solution.AssetManagement.Asset and Solution.AssetReporting.Asset