I am writing a control app for a 6-DOF robot. This app can send scripts to the robot, which in turn executes these and thus moves around. In the app a robotprogram can be created by adding 3D coordinates called a point(class). This robotprogram is simply a Model with a List which contains all points. Also a few functions for adding points with default coordinates or based on the current robot position. There are 5 different types of points which all compile different lines of script e.g. the robot going to the point but also clamping with its gripper.
In the robotprogram Model the list is of type ObservableCollection. This type of collection is Microsoft specific and basically allows functions to register to it, these functions will be invoked if an item is added or removed (optionally changed).
In the ViewModel I simply added another ObservableCollection that references the one in the model. The View uses the collection from the ViewModel and thus in turn the one from Model. The View uses the collection to show a list of points which can be selected to see point specific data and change it e.g. the coordinates. Adding/deleting a point is done via a button in the View, this is wired to the ViewModel which in turn calls a function from the Model. Based on some business logic the point gets added. This addition to the Model gets relayed to the View and ViewModel throught the INotifyPropertyChanged from the ObservableCollection thus the View gets updated.
This works fine, but this coupling has caused me to add a field to the Model that does not belong there. Namely IsSelected (boolean) to every point in the List. The reasoning is that due to not being able to persist state about checkboxes on the View it has to be stored somewhere.
It's hard for me to come up with the right questions to ask about this architecture, since I don't know what is good and bad; or how to structure something like this. Three things come to mind:
- It seems "obvious" that coupling View to Model is bad. Do I fix this by getting the nodes from the Model in the ViewModel and transforming it to the Views needs i.e. some type of adapter/proxy pattern? How would this work with INotifyPropertyChanged e.g. adding a point to nodes in the Model should be reflected in the View, thus the transformer in the ViewModel should facilitate this somehow?!
- Similar questions mention Data Transfer Objects (DTO) to be created by the ViewModel and send to the View. How would this handle changes back and forth from View -> Model and Model -> View.
- The robotprogram Model has a List that is seemingly used all over the place, remove and addition of points is done through the Model but Deserialising/Serialising/Generating script is all done outside the Model but based on the List in the Model. Is this some code smell or is this normal? Also how would I change this, I could add all functionality to the Model but it will get huge that way.