Search code examples
core-dataumldatamodeldata-modeling

How should I model that some instances cannot be modified?


I'm creating a data model using xcode and core data. It's an object graph, not entity-relationship model, so I have inheritance and many-to-many relationships.

This is my problem: I have a class or entity called Category. Some categories are created by the app and cannot be deleted or modified by the user. Users can create their own categories.

After thinking about it, I found 4 ways to model this. See the picture:

enter image description here

I guess the most practical solution is just adding a flag, isSystemCategory, but I wonder what is the best solution from a modeling point of view. I guess the first one. An abstract class called Category, and 2 descendants, UserCategory which is editable and deletable, and SystemCategory, which is inmutable, users cannot delete it or modify. Note that descendantsdo not add any attribute, relationship or any change, so, that's the reason of my question. Is this a correct approach for a modeler?

I would like to know your ideas. Thanks.


Solution

  • Based on description I'd probably go for the first one too.

    Note that descendants do not add any attribute, relationship or any change

    But the behaviour is different. And there's a logical difference too. There is an implied 'relationship' between User and UserCategory that allows a User to create/update/delete a UC. You may not need to hold this explicitly but it's there nonetheless (and you might capture it e.g. if you want to record who created/modified/deleted the category).

    Creating separate subtypes will prevent a fair bit of nasty conditional logic that would otherwise crop up if you used e.g. a flag. Think of deletion: with a flag you'd have an if (category.isUserCategory) then <delete> else <...etc...>. Furthermore that logic would be replicated for each operation that behaves differently for user- vs. system categories. Using subtypes removes that: UserCategory.delete() just does it, SystemCategory.delete() just doesn't (there might not even be a public delete on SystemCategory). No conditionality.

    One final thought: the problem here is really about authorisation. If dealing with categories is the only place it comes up, then your option (1) is probably a pragmatic solution (the 'simplest thing that could possibly work'). If you have a recurring need to control access however, you probably should use a more general authorisation mechanism.

    hth.