Dylan: Testing for mixin inheritance


A recommendation for good program design that avoids directly testing the type of an object.

In general, do not directly test an object's class like this:

  if (instance?( obj, <my-mixin> ))
    // mixin-specific stuff
  end;

Instead, define a predicate with a default method on <object> or some other appropriate superclass that returns false, and a method specialized on your target class that returns true:

  define method my-mixin? ( obj :: <object> ) #f end;
  define method my-mixin? ( obj :: <my-mixin> ) #t end;

This provides better encapsulation and makes it easier to change the conditions for the test, rather than relying upon simple inheritance from a particular class. In fact, try to define one or more predicates that test for specific capabilities, if possible, rather than just testing whether an object is a member of the mixin class:

  define method fooable? ( obj :: <my-mixin> ) #t end;
  define method barable? ( obj :: <my-mixin> ) #t end;

This applies to classes of all kinds, but I was reminded of this when I came across some old Dylan code I wrote (circa 1997, when I was still young and naive) that used the direct instance test to filter mixin-inheriting objects from objects of the primary class usually associated with the mixin class. I think it’s probably easier to make this kind of mistake when dealing with mixin classes, where the programmer’s attention may be focused on the classes involved (mine apparently was back then), rather than on the capabilities expressed by those classes.

Posted: Sun - March 14, 2004 at 04:48 AM          


©