0

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:

  1. 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?!
  2. 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.
  3. 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.

1 Answer 1

1

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?

Yes.

Adding a point to nodes in the Model should be reflected in the View

Models don't usually work like this. If you need real-time communication, you need to use a real-time communication mechanism like sockets or the Observer Pattern. You can continue to use ObservableCollection if it works, but I don't see what "IsSelected" has to do with that. The model should only need to know that a change occurred.

Deserialising/Serialising/Generating script is all done outside the Model but based on the List in the Model. Is this normal?

Where outside the "Model?" If you're referring to outside of the DTO's but still within the "model," yes, this is normal.

2
  • I should probably clarify the last point. With (De)serialising/Generating script I mean that I use the List<T> which resides in the Model class Robotprogram outside the Model class. Meaning I have a class ScriptGenerator, which uses the List<T> straight from the Model. As for the second point: the Model is simply a class and has no database or socket connection. Also the IsSelected is somewhat confusing, but essentially an extra field in the point class which is used in the List<Points> in the Model. Transformin the Model in the VM should fix this. Jun 22, 2021 at 15:20
  • Should the ViewModel register to changes in the Model to trigger the transform function on the List<t>, to reflect these changes back into the View? How is this usually done in MVVM, I simply can't find anyone doing this; almost all examples I find simply bind directly the View to the Model (which imo is incorrect). Jun 22, 2021 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.