|Subject||Re: [IB-Architect] Table Inheritance|
>If we need interfaces (why do I want to type InterFaces?), we needJim, the difference is this:
>them. But lets not go looking for a home for them right now.
1. With Inheritance, the relationship of table to trigger is one of
containment. Meaning, the trigger is contained in the table. Thus the
trigger is tightly bound to the table. So, the semantics / checking is done
at compile time.
meaning: the trigger is defined to be within the table definition. This is
in line with your proposal that triggers are to be defined at base tables
and these base tables (along with triggers) are to be inherited by those who
wish to gain the functionality of the trigger.
So, also note that those tables who wish to get the functionality of the
trigger should do so at definition time, and should use inheritance
create table xxx extends base...
Also note, that the link of the xxx to base is hierarchical -- xxx being a
subclass of base
Also, when you create the table xxx, this means that you automatically also
inherit all the triggers of the base, etc... which is the mess you are kind
of worried about.
So, keywords: INHERITANCE --> definition at CLASS level --> binding
static --> semantics can be determined at definition time.(DDL)
2. With Interface, (note that Interface is implemented at object level ->
meaning it is a relationship between two separate objects), triggers an
tables are considered two separate and distinct objects. Only we know that
the object table can use object trigger. And generally speaking, in the OO
world, the semantics of this relationship - being on the object level,
should be at runtime (after all, that's when the objects are instantiated
So, a single trigger object can be related to many table objects, and a
table object may be related to many trigger objects (many-to-many
The important implication is this: because the semantics is on run-time
(DML), this means that you don't need to check the correctness of these
triggers (mainly the existence of new/old variables in tables), at
definition time. You can place this at run-time and at the responsibility of
the designer/programmer. So, this realization should speed up a lot of
things because you can forego constraint checking. All you need is the blr.
Also note the implications:
with Inheritance, inherited triggers should most probably be flattened out
and redundantly redefined (as in rewritten), in its subclasses. There would
be the propagation problem you are mentioning.
Thus the advantage is: Referential checking is done with regards to new/old
disadvantage is: redundancy and complicated propagation (of system
with Interface, triggers being separately instantiated entities (objects)
from tables, the link is looser and can be done through "relationship"
instead of "hierarchical subclassing".
One single interface trigger can be related to many different tables (and
because the link is relationship, the trigger need not be rewritten for
every table. nor semantic checks done at definition time).
Understanding that Interface triggers are separate from tables (though they
exist to be used by tables - like hammers are separate from man though their
raison de etre is to be as tools of man), means Interface triggers need not
be redundantly rewritten.
An analogy is this:
Suppose I want instances of: A man with a hammer.
I. Inheritance: create table man ( body ); create table
an_with_hammer( hammer ) extends man
2. Interface - create table man; create hammer; set hammer to man[, man2,
So, with inheritance, the hammer becomes an inseparable (tightly bound)
entity within man_with_hammer, and the inheritance relationship is
With Interface, it is looser.
I'll try to look up the book on Design Patterns which I've read around two
years back, and which really helped me a lot with OO analysis and
One very important point that the Design Pattern book brings home was this
failure to distinguish when to use inheritance and when to use interface.
If we conceive tables as having triggers that are so totally linked up to
tables that the tables cannot exist without triggers and vice-versa, then,
we should go with Inheritance as you suggest (like the base table, and
extends mechanism). -> and the implication is: semantics / checking is fixed
at design time. --> meaning the compiler (or DDL) should trap semantic
errors like non-existent NEW.Variables.
[Here, the table owns the trigger and the trigger owned by the table cannot
be owned by another table]
But, if you can conceive triggers that can exist separately from tables, and
can even be assigned to multiple tables such as the time-stamp trigger, then
it should be implemented as an interface trigger -> meaning: instantiate the
trigger separately from the table, have the relationship used_by instead of
owned_by, and the semantics checking are not verified at compile time.
Errors are only realized at run-time.
So, I guess the new keywords are:
Triggers owned (exclusively by one) table(s) -> Inheritance [ functionality
passed through subclassing],
Triggers used by (maybe, many) table(s) -> Interface -> trigger a separate
instance from table. [functionality passed through relationship as in: SET
TRIGGER XXX TO TABLE1, TABLE2, ...
Inheritance: Static (you can't change your parents) - definition made even
while you are defined at the womb:
Interface: Dynamic (you can use your tools) - decisions made in the real
I hope that I have shown that realizing the distinction between Inheritance
and Interface makes a lot of difference and finesse.