views:

56

answers:

2

I'm working on a RoR app, but this is a general question of strategy for OOP. Consider the case where there are multiple types of references that you are storing data for: Books, Articles, Presentations, Book Chapters, etc. Each type of reference is part of a hierarchy where common behaviors sit at the most general point of inheritance, and at the DB level I am using single-table inheritance. The type is set by use of a select option, so lets say that I was entering the data as if it were a Book, but then realize that it is only a chapter. So I change the type of reference by selecting "Book Chapter", which then posts an update to the existing model/form. The question is what is the correct strategy for handling this?

On one hand it seems preferable to transform the existing record in the DB to avoid id exhaustion, and potentially save on operations for creating/deleting records. This however tends to make the update strategy complex.

On the other hand, it seems more in keeping with general object orientation to create a new object (and record) using the old object to initialize values that you want to persist, then delete the old object. This I think makes more sense in terms of an Object Space (heap), and I think is more aligned to ideas like those of general systems.

However, I haven't nailed this down, and after sitting on it for a while, I'm pitching it to this community to see what "right" way to do this is.

+1  A: 

The transformation you're talking about doesn't seem to warrant a new record or even a new object.

Each of the entries you cited have the same form. They are block of text with siblings, parents and children. A chapter may have a block of text, with a parent book and a child endnote, for example. They are differentiated on a DB level only by their type, which itself could be a field.

All you need is a model to handle these 'elements' differently depending on whether or not it is flagged as a book, or a chapter, etc. If an element is flagged as a chapter, yet has no parent, for example, then you might flag it as a 'book' when it is saved to the DB.

Changing the way an element is flagged doesn't change the element, it only changes the way it is viewed. So long as the element knows how to find it's children the data will compute in the same way. As far as the model is concerned it's just an element you're worrying about. The rest is done in the UI.

deau
I agree. If your models are similar enough to warrant single table inheritance then either of these options would be way more work than is actually necessary.
Azeem.Butt
Perhaps I should have used a 2nd example. This isn't just about storage of the data but the ways the data behaves. Another example would be where we are creating scripts for a game, and records represent expression nodes. So lets say we've got an Effect class, and there are things like Give and Take effects, but GiveMoneyEffects have different requirements than GiveItemEffects that require item selection as well. In this case there are form behavior changes, as well as processing-time issues.What is the "right" thing to do then?
@adamaig Well, the right thing to do then might be to create a new object with a different subclass. Alternatively, you could just have a behaviour field that your model checks for. If your using Ruby you might prefer to use metaprograming to give an object it's own functionality at run time. As @NSD commented, the right thing to do will depend on the dimorphism of your models and the language/paradigm you choose to work with.
deau
+1  A: 

Prefer immutable objects, in other words: the second strategy. Your objects may not be immutable by themselves, but reducing mutability is often a step in the right direction.

Besides that, this is the more natural way. In general OOP terms there's no way to change the type of an object. In your situation you can, but it's still an awkward and unusual thing to do.

On the other hand, if your objects are represented by the same (identical) class and changing the type is done by setting a high-level property, one could argue that re-creating the object is overkill.

Still, reducing mutability is a good think, but if your class is already designed to be mutable, it might not be worth it. (In that special case where there's actually only one actual class from the language point of view)

DR