I watched the WWDC 2015 video about protocol-oriented programming and value semantics. Both of them use the example of a diagramming app, where the user can make a diagram of circles and polygons. They make a protocol for Drawable (makes sense), and then make Circle and Polygon structs.
I'm working on rewriting a long-term project of mine in Swift. It's a schematic capture CAD app, and it draws schematic diagrams built up from instances of parts from a library, and wires between them. Currently, my model is entirely made of classes, with reference semantics. I'm trying to see if it wouldn't make sense to make them structs with value semantics, but I don't think it does, and I'm looking for advice.
My model consists of the following objects: PartDefinition and PartInstance, as well as some geometric primitives. A PartDefinition has a set of properties (e.g. UUID, name, value), and a set of geometric primitives. The geometry defines the appearance on screen, and the properties give the part identity in the schematic. A PartInstance references a PartDefinition, and adds a position property (to define that instance's location in the canvas), as well as overriding zero or more of the PartDefinition's properties, or adding its own (for example, a PartInstance gets a Reference Designator, just a label for the instance, like "R1" or "U23"). A PartInstance rarely, if ever, overrides or adds geometry found in the corresponding PartDefinition.
The reason I don't think these work so well with value semantics is that they can be edited by the user: they can be repositioned, properties can be changed, etc. Even the geometry of a PartDefinition can be changed, and the intended result is that all instances displayed in the canvas reflect the new geometry.
Similarly, in the diagramming example from the WWDC videos, how would that app handle the user editing existing Drawables in the Diagram? Let's say you allow the user to click on a Drawable and drag it to another location in the canvas. Is this reasonable:
- User clicks with the mouse
- Find the item hit by that click by iterating through the array of Drawable
- var currentItem = self.items[hitIndex] (makes a copy)
- update currentItem with whatever changes have occurred
- self.items[hitIndex] = currentItem (copy the new values back into the array
- set window needs update
It seems like reference semantics are more appropriate here.