Re: Vertical inheritance with a non-abstract superclass
Re: Vertical inheritance with a non-abstract superclass
- Subject: Re: Vertical inheritance with a non-abstract superclass
- From: David Elliott <email@hidden>
- Date: Mon, 10 Mar 2008 15:43:46 -0400
On Mar 10, 2008, at 11:35 AM, David Avendasora wrote:
Nathan,
I think you will find that Vertical Inheritance is much more
resource intensive than you'd think. David Elliotts email points
this out in that if query an object of the superclass or any one
subclass is requested, it does a query for each possible subclass as
well. So if you have 3 subclasses, it will do 4 queries, even if you
are only trying to instantiate one of the subclasses, or even if you
are just trying to instantiate the superclass.
Woah. Hold up there. If you fetch one of the subclasses you will see
one query. It will join the subclass table with the base table.
That's it.
It's only when you fetch the base abstract class that EOF must
necessarily use one query for each subclass. That is, after all, the
entire point of vertical inheritance.
With single-table inheritance, if you are loading the superclass,
even though the query may bring back all the fields for all the
subclasses as well, it does it in one DB operation, that is going to
be much less overhead than what VI does.
To me, Vertical Inheritance should be viewed as something to use
when you are trying to make use of data in a legacy database, not as
a tool for designing a new database.
Vertical inheritance has its place. I think a lot of people on this
list and even writing the literature have a tendency to discount it.
That said...
Also, because of the way WO uses faults, what you are trying to
avoid likely isn't even a problem in the first place.
If the only reason you are using Inheritance in this situation is to
split off attributes that aren't required, then I think you're going
to want to really reconsider using Inheritance at all.
As far as making it work across models, is this a new project or an
existing one? It sounds like you are trying to implement many of the
more complicated EOF concepts in a new project.
The biggest problem with vertical inheritance or really any sort of
inheritance in EOF is that it necessarily complicates your model.
That said, if your data model really does have a vertical-inheritance
structure to it and you really think that's the best way to model it,
then you OUGHT to model it that way.
The biggest mistake with EOF inheritance is to use it purely for
polymorphism. If you use it because you really do want additional
attributes in the subclasses then you're doing it right. But keep in
mind that once you create an object of a given class there is no
converting it to another class. If your data model requires that you
be able to change some property (e.g. attribute or even a to-one
relationship) of an object and have it magically change classes then
you are definitely modeling it wrong.
If D2W is involved, inheritance of any sort can be somewhat of a pain,
particularly in the case of owned to-many relationships to the
abstract base class. At one time I implemented a quick hack that
simply changes the new button to jump to a little dialog-like page
where the user must select the subclass.
This does however bring up yet another point. Do NOT use inheritance
if the only commonality in the data-model between your subclasses is
that they are owned by the same object (i.e. they have a to-one
pointing back to their owning object). And still don't use it if the
only commonality is a handful of attributes and to-one relationships.
In that case you can very likely have a separate to-many from your
owning object to each type. You may as well model it this way because
ultimately that's exactly what EOF is doing.
You may in this case have some attribute common to all like a
totalAmount (e.g. a cost or price). And in that case you may be
better off taking advantage of the fact that
valueForKey("totalAmount") works regardless of the type of object so
long as it has key value coding. And if you want to do totalAmount()
then possibly define yourself an interface with that in it. You can
synthesize a to-many relationship to an array of this interface or of
EOGenericRecord by simply concatenating all of the real to-many
relationships. You can even go as far as to synthesize a setter and
add/remove object methods if these help you programmatically work with
your model.
But again, it all boils down to one simple fact: Do not use
inheritance for YOUR benefit. Find a different way to get polymorphic
behavior. Recognize that KVC effectively makes every property its own
interface (because valueForKey("foo") or takeValueForKey(bar, "foo")
works on any object with that property. This is ultimately a watered-
down version of an Objective-C truism. Namely that every method
selector effectively implicitly defines its own interface with exactly
one method.
Use inheritance when the data model demands that you do. Never
because you think it's going to make your life easier. In the end it
will not unless you have hit that one very special case where the data
model does demand that you use it and then it will make your life a
whole lot easier. If your data model doesn't demand it, it will make
your life a whole lot harder. Recognizing what does and doesn't
demand it is the difficult part. It's one of those hard choices you
have to make.
Make it work. Then make it work right. THEN make it work fast.
This is actually an argument for vertical inheritance, not against
it. Make it work often means using vertical inheritance. Make it
work right can be re-evaluating whether inheritance of any sort is
actually appropriate. Make it work fast can mean deciding to do single-
table or horizontal inheritance to improve your speed if you really
have to.
That said, vertical inheritance really is the cleanest data model of
all the inheritance types so don't shy away from using it when it
really is appropriate.
-Dave
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden