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