I'm creating a simple network application that communicates with one or more services, so I planned to use some queues (for outgoing messages and incoming ones), a table, a list containing the status for each active connection, etc.: in other words, these are the data structures needed to ensure the functioning of the application itself.
This application must also be equipped with a graphical interface that shows part of the internal functioning of the application itself: for example, the filling status of queues, the status (detected speed, etc.) of the connections, etc.. According to the Model-View-ViewModel pattern, the model consists of the data to be displayed in the GUI: in this application, the aforementioned data structures represent the model. In other words, the Model implements the business logic of the application.
The ViewModel should implement INotifyPropertyChanged interface in order to notify the View that a change is occurred, but how does the Model to communicate with the ViewModel? After reading this article, I realize that the INotifyPropertyChanged interface is implemented by the model. This answer explains a little more, but it confuses me a bit:
INotifyPropertyChanged - Should go into ViewModel and Model (if needed)
Why, if needed?
When should I implement this interface?
When should I not implement it?
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
how does the Model to communicate with the ViewModel
Any way you want it to. In most of the apps we write, the view model makes calls to the business logic layer (the model). However, if you have a need for the view model to be notified immediately (events) of changes to the model, you could implement INotifyPropertyChanged on your model. Or you could simply have the view model subscribe to events on the model.
Moreover, the Dictionary does not implement the INotifyPropertyChanged interface: if I use it, should I wrap it with a class which implements this interface?
You only need to have the view model implement INotifyPropertyChanged. Properties within the view model (dictionary) will simply invoke NotifyPropertyChanged (or whatever your implementation looks like).
Finally, the model should be read-only, meaning that the user does not be able to change the contents of internal data structures using the GUI. How to accomplish this?
Don't provide the user the functionality to let them change the data. Make the binding one way, or simply don't provide them an API for making changes.
INotifyPropertyChanged is primarily implemented by the ViewModel classes. This is to facilitate the data-binding so that the UI controls in the view that are bound to the ViewModel property will be updated when the property is modified.
In the MVVM design pattern, the relationships are very simple and in a single direction. The View knows it's ViewModel and a ViewModel knows about the Model. If the Model is updated, the ViewModel needs to know somehow so that it can reflect the update and propogate it to the View. One way is to also have the Model implement INotifyPropertyChanged and have the ViewModel implement the corresponding event handler. If all the changes are driven from the UI and being pushed back to the Model, then this is probably not necessary.
You can't really bind to a Dictionary. Using an ObservableCollection would be ideal if that works in your case. Or, you can take a look at implementing an Observable Dictionary along the lines of this: http://drwpf.com/blog/2007/09/16/can-i-bind-my-itemscontrol-to-a-dictionary/
MVVM has provided separation of the Model from the View, so there should be no direct relationship from the View to the Model. The implementation of the ViewModel controls what, if anything would ever get written back to your Model.
INotifyPropertyChanged (INPC) should never be in the model unless the model is also the ViewModel (i.e. you don't have a "model"). INPC should only ever be in the view model.
The model should know nothing about the view model, and thus can never communicate with it. Only the view model can communicate with the model.
From the UI point of view, only the view model does anything with data; so, if you want the model to be "read only", then just don't implement that in the view model.
Binding would be done with the view model, in which case don't use Dictionary (unless you want to write the code to wrap that in order to bind it). If the Dictionary is in the model, then you should be "wrapping" that in the view model--it's fairly trivial to write an observable wrapper around a collection. In all likelihood your view model isn't going to deal with key/value pairs--it should be dealing with something flat that the UI can handle (and be bound to).
UPDATE:
INPC was introduced for data binding. It decouples a view from a particular concrete class so that it only needs to know about INPC (notice the direction of decoupling). In terms of MVVM this decouples the view from the view model, in the case of PM, this could decouple the view from the presenter, in the case of MVC this could decouple the view from the controller, in the case of MVP this decouples the view from the presenter.
Data binding is a technique of binding data to UI elements. It binds a data source to a target so that the target may request data how ever it sees fit or the source can push data however it sees fit (depending on the type of binding--it could be one-way or static, restricting how often get/push can occur).
Sometimes the necessary nature of the decoupled relationship between the data source and the target lead people to believe data binding isn't a UI concern and data binding can apply anywhere. i.e. a data binding implementation is completely decoupled from a UI. This is generally a mistake. Data binding decouples the view from the specific knowledge of specific classes (this is basic layering and avoidance of cycles, that I won't get into here). But, it doesn't completely decouple the view from the data source. Binding can't happen without the data source--there is still a level of coupling there, it's just the compile-time coupling that has been alleviated (aids in testing, flexibility, robustness, etc. but must be present at runtime in production. i.e. the fact that the INPC implementation can be tested without being bound at runtime to UI elements doesn't mean it's not dependant on a UI framework). The fact that the view is still loosely coupled to the data source isn't the only coupling in this relationship. The data source is loosely (if not less loosely) coupled to the view by way of its UI framework.
Every UI framework has a restriction that access and modification of UI elements must be done on the main, or UI, thread. (at least on Windows; it likely happens on other platforms, I'm just not proficient in any others). With data binding, the source is indirectly bound to the control and any data change directly changes one or more UI elements (depending on the framework you can have intermediaries. Like value converters in WinRT, but their responsibility is to transform or convert data). This means that the data source needs to have intimate knowledge that it is bound to a UI and what type of UI framework it is binding to. This tight coupling to a UI framework clearly couples the data source (still loosely) to the UI.
This means any particular implementation of INPC is really bound to one and only one UI framework. That object can no longer be used anywhere (obviously anywhere is an ideal, it's often impossible to make anything work for every scenario--the point here is high cohesion in more than just one or two scenarios). e.g. if an implementation of INPC is used in a multi-threaded environment then it needs to "marshal" data back to the UI thread before sending out property notifications. In WinForms, that's Control.BeginInvoke, in WPF and Silverlight that's via System.Windows.Threading.Dispatcher. In WinRT, that's via Windows.UI.CoreDispatcher. In all cases the INPC implementation must take a direct coupling to one UI framework. In the case of Silverlight, that's a direct coupling to either the "desktop" Dispatcher or the Windows Phone Dispatcher.
Quality metrics include concepts like cohesion. Cohesion is a measure of how strongly related two units of code are. An implementation of INPC that is used by something other than the UI, due to the nature of all the infrastructure required to support that one particular UI framework, although potentially able to be used outside of the UI, will have low cohesion because all of the code relating to the UI framework will not be used. i.e. it's take on too much responsibility to be completely decoupled from the UI. Yes, you can use an object that implements INPC anywhere and never use the PropertyChanged event, but then you have low coehsion (considered bad).
If I implemented INPC in my model and I wanted to use that model with both my UI and my WCF or web service back end, I either couldn't or my backend would have to take a reference to some UI framework. If I wanted to use that model in another type of UI, I couldn't, because that INPC implemetnation depends on one particular UI framework. I'd have to write another "model"; at which point it's clearly a "view model".
INPC itself is not bound to a particular UI framework (nor should it be). This leads to the misconception that INPC can be used anywhere. Yes, its lack of coupling to high-level namespaces means it can, but the overwhelming usage of INPC is when the target is a UI. I'd challenge any other uses of INPC that don't involve a UI as true "binding". As with any other tool, you can misuse it to get useful results. INPC could be used for projecting data, it could be used for transforming data, etc.; but I believe those are misuses of INPC and really outside the focus of this question...
Related
In learning Xamarin.Forms/UWP/WPF tutorials always tout MVVM as the design pattern of choice and I've followed suite, but I've never understood why. To contrast, in asp.net MVC the templated framework is used to great effect, Controllers deliver models to the view (HTML of some sort).
But in the Xamarin.Forms/UWP/WPF and others, we create a completely new class, ignore the code-behind file that cannot be removed and relegate it to telling our view where to look when binding data.
The only reason I could think of that makes MVVM better is if we could supply logic where different VM's could be 'injected' into the same view, maybe that would justify it.Though I have no idea how to do that.
Otherwise, how is creating a view model class better than using the code behind file? Is it really worse separation of concerns just because the view and code behind have the same name and are instantiated together?
MVVM pattern is much cleaner than using code-behind.
Separation of concerns
Imagine you have a view and a code-behind implemented. Now the business comes with a request to completely change the way the controls are presented - replacing them with new controls, changing layout and so on. Chances are, you will be forced to rewrite a lot of code just to satisfy the requirement, because the code-behind is directly tied to the view.
Now in case you have MVVM in place, you can easily swap the View part of the equation for any view which utilizes data binding to the right properties in a View model. You could easily present a single View model in several different ways - like creating multiple different views for different user roles while the view model stays exactly the same, you just choose what to display and how.
What view model actually creates is a middle layer between data and their presentation and makes it possible to more easily transform the data the view uses and change the presentation without affecting the view model if the interface is kept intact.
Data binding
Also if you are meaning purely code-behind without data-binding, the advantages of MVVM become even clearer. When you have a data-bound property that updates after user input in a TwoWay manner, for example if you have a form the user has to fill out, you don't have to remember to fetch the latest "changes" from the control using Text property, you know the latest version is already there in the data-bound property. In addition, you can add validation in the property setter, you can update other properties in the setter as well to orchestrate data handling in a much more abstract way than with code-behind approach, where you are tied to events and having to remember where the data come from and which specific controls and which specific properties you have to update. Imagine you display a given text in multiple places - with data binding you just set a single property and rely on {Binding} to display the text in all bound controls. With code-behind only, you need to remember which concrete controls display the text and when you add a new control, you have to update the code-behind appropriately, which is far less convenient.
Cross platform development
Another example would be having to develop a cross-platform application with native UI using MvvmCross. Here you can decide that some views or some functionality will not be available for certain OS or that you want to just implement it later. This is entirely possible - you just don't provide the UI for that functionality and the view model can stay the same.
View state
Finally - having all view state in code-behind means that when you navigate away, you must store the state somehow and restore it when navigating back because a new page is created. With MVVM you may decide to keep the view models of the navigation stack in memory and when navigating back just set the DataContext of the page to the existing view model instance to get back just in the same state as you left off.
Overall I see MVVM as a great pattern to improve flexibility of your codebase and it makes your solution more future-proof and resilient to changes.
considering a situation where only the user updates the ViewModels/Models through the UI, there's no external access to the data displayed.
Why does the ViewModel should implement INotifyPropertyChanged in this case?
It makes only sense to me to have a ViewModel implementing it when there's external access to the data so that the UI has to be notified somehow about an external-initiated property-change and you set up Mode=TwoWay/Mode=OneWay.
Most of the sample MVVM implementations I saw never subscribe anything the the ViewModels PropertyChangedEventHandler, but still implement it, just because it has to be done, since it's mvvm.
If the user changes one item in the view it may affect multiple items in the viewmodel, or it may affect the state of one item in the viewmodel that in turn affects the presentation of multiple items in the view.
I would have to turn the question on its head and ask, given the above statements, why would you not implement INotifyPropertyChanged? It's hardly a massive overhead.
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'm currently using Model View Presenter Passive View on my .NET Compact Framework project using C#. Now, in my model, I have lots of Pinvoke from a C/C++ DLL. My project is a hardware testing equipment, typically with buttons and large LCD touchscreen. It then collects data (uses some database) and transfer to PC.
I created a model interface, and the class that implements it invokes those Pinvoke methods. One reason is I would like to encapsulate the Pinvoke and marshalling,interop inside the Model.
Now I have a presenter. An example scenario: a user presses a button then the click event on the view will call the method on presenter (via an interface), then finally call the model's method (via an interface again).
Now, it seems to me that the presenter is mostly becoming a wrapper of the model's business logic. If I add some methods to the model, I also need to add that method via an interface because the view's button's need to invoke some of the methods in the model. I feel that there is too many indirection. One example is that, in the model, I have a thread to wait for the events being pushed by a C/C++ DLL. Now, I have a thread on the Presenter which uses an observer pattern to queue and process that events coming from the model (changing of screen views and telling the user what is happening).
pseudo code
from the interface of view:
void viewChangeTestResultsText(string Text);
from the interface of presenter:
void PerformTest();
on the concrete class the implements the interface of presenter:
void PerformTest()
{
interfaceView.viewChangeTestResultsText("Test Started");
interceModel.PerformTest();
}
on the interface of Model:
void PerformTest();
on the concrete class of the Model:
PerformTest()
{
ModelPinvokeMethods.PerformTest();
}
in this code, the button click handler calls the performtest in the presenter, then presenter calls the performtest in the model. then model calls the pinvoke performtest. the indirection quite causing some pain already because I have lots of method calls to implement and the project is in a very tight deadline.
For my project, there is another variant and I know that I will be needing a changeable presenter and with this, I also need a changeable model because the business logic is somehow different although there are lots of similarities. Right now, I am thinking of pushing all the logic in the model to the presenter so that I will just be maintaining only the logic on the presenter view and use the model only for data handling (database, configurations, settings), which I think will be simpler in terms of development and code maintenance but I am not sure of the impact in terms of flexibility.
This is my first time to use MVP in passive view. I am not sure if I am missing something regarding the correct implementation of MVP. Any thoughts or suggestions on this?
Your understanding of MVP seems fine; you have correctly distinguished between presentation logic (perform test, synchronize view) and domain logic (PInvoke). With the interfaces you have set up, you can easily unit test the presenter (which is one of the main advantages of using MVP).
I would advise against putting all of the logic in the presenter as that can lead to a God Object.
Regarding your changeable presenter problem, I'm not sure what you mean. Do you mean that you need a different presenter/model for each type of device? If so it seems perfectly reasonable to have a MVP-triad for each type of device if they are sufficiently distinct from one another. If you identify common traits between them, you can either use inheritance or utility classes to provide common code.
I am using MVVM with WPF, but I am having a hard time understanding the concepts behind this desing pattern.
I have a "myclass" object that is the state of the application (it stores data loaded from the repository). All pages of my application will use this data and the object should be syncronized between them all.
My first approach was to store this data in the service layer, using a singleton class. So, all ViewModel should call this service to get the data. Any modification should also call this service, and a event would be fired to synchronize all views.
I am wondering now if it would be better to store this data in the model layer...
What's be best option?
EDIT:
Adding more information:
The data stored is a list of projects loaded into a solution. Since there must be only one solution, I implemented it as a singleton. The must can interactively load, change, or remove any project.
A Service to my understanding is just something that abstracts a piece of functionality(access the file-system, access a database...) which say implements a given interface that the VM's can then use when requiring that functionality.
A Model however holds the business logic of your application and anything that will assist performing that business logic (which can / cannot implement INPC if desired)
So in essence you use a service to get something done and let go of it, a Model is more ingrained to your application
For your given use-case, I'd have the stored info in the Model and implement INPC on it so that the ViewModels get notified of changes automatically if another ViewModel makes a change to the Model.