Developers Manual 1.20

1. Defining the Object Model

1.6 Inheritance

At the start of this chapter, it was mentioned that defining a class for ReStore enables a database table to be automatically constructed for that class.With a hierarchy of related classes, it is necessary to decide whether these should share a single database table, or should each class exist in its own individual table (or possibly some combination of both). By default, a hierarchy of classes will share a single table. 

To illustrate the concepts discussed in this section, we will consider the StockItem hierarchy from the Entertainment Shop example application; it is worthwhile studying this before proceeding:

StockItem - code, title, price, numberInStock
    CompactDisc - artist, tracks
    VHSVideo - director, genre
        DVDVideo  - extrasDescription


Advantages of Sharing a Table
When a hierarchy of classes share a single table, some important possibilities are opened up. Firstly, if you define an instance variable in another class as holding instances of the superclass of a hierarchy (StockItem in the case of our example), then in fact that instance variable can hold an instance of the superclass or any of the subclasses sharing the superclass table. In the Entertainment Shop application, this is done in the OrderItem class definition method:

addClassDefinitionTo: aTable

        aTable
                define:
#stockItem as: StockItem;
                define:
#price as: (ScaledDecimal withPrecision: 8 scale: 2);
                define:
#isStockAllocated as: Boolean

Thus an OrderItem can hold a CompactDisc, a VHSVideo or a DVDVideo instance in its stockItem instance variable.

A second advantage is that when you need to query for objects in the database, then a query for instances of the superclass of the hierarchy will also find instances of any subclasses sharing that table. Again, the Entertainment Shop application takes advantage of this in the class StockItemFinder:

findItems

        "Find StockItems using the title and type infor input by the user.
        Uses ReStore specialised querying methods"

        | found numberFound |

        found := self reStore instancesOf: StockItem satisfying: [ :item | self title match: item title].
        ...

This method will in fact find instances of CompactDisc, VHSVideo or DVDVideo.

A final advantage of sharing a table amongst a hierarchy of classes is that, should you need to query the database from a source other than your Smalltalk application (a reporting tool, for example), then this may be simplified by the fact that all the objects are located within one table.

 

Disadvantages of Sharing a Table
When constructing the single shared table for a hierarchy of classes, ReStore will allocate a column for every (non-collection) instance variable in each class. Thus, when for example an instance of VHSVideo is stored in the table, the columns corresponding to artist (a CompactDisc variable) and extrasDescription (DVDVideo) will be empty. This is effectively wasted space in the table.

If there are large differences in the instance variables held by different subclasses within a hierarchy, you should possibly consider storing the subclasses in different tables to avoid this waste of space. This does mean that the advantages of table sharing listed above are lost. However, if there are large differences between the classes in the hierarchy, then it is likely that they are not related in a meaningful way and so the loss of these advantages may not be important. 

A common situation where this is the case is where there is one abstract superclass, defining a few common attributes, for all model object classes in a particular application. Example:

MyModel - description, dateCreated
    Person - surname, firstName, address...
    Address - line1, postcode, city...
    Product  - name, code, location...

In a case like this, then it is highly unlikely that you would want instances of Person, Address and Product to share a table. To turn off the default behaviour of hierarchies sharing a table, MyModel should implement the following simple class method:

shouldSubclassesInheritPersistency

        ^false

Should you wish to turn table sharing 'on' again in a sub-hierarchy, you would simply override this method to return true

Alternatively, or in addition to this, individual subclasses may choose to 'opt out' of sharing a table by implementing the following method:

shouldInheritPersistency

        ^false

Note, however, that a subclass cannot 'opt in' to table sharing where it has been specifically turned off by a superclass implementation of shouldSubclassesInheritPersistency.

The use of these two methods is documented further in their implementation as Object class methods, where the default behaviour is defined.

 

Don't forget super
Whether sharing a table or not, it is important that when subclasses implement their addClassDefinitionTo: method they should also forward the method on to their superclass in order to include the definition of the superclass's own instance variables. Example:

CompactDisc:

addClassDefinitionTo: aTable

aTable
        define:
#artist as: (String maxSize: 200);
        define:
#tracks as: (OrderedCollection of: CDTrack).

^super addClassDefinitionTo: aTable

StockItem:

addClassDefinitionTo: aTable

aTable
        define:
#code as: (String fixedSize: 12);
        define:
#title as: (String maxSize: 200);
        define:
#price as: (ScaledDecimal withPrecision: 8 scale: 2);
        define:
#numberInStock as: Integer

 

1. Defining Classes

© 2000-2003 Solutions Software Ltd.

Home | Index | Next