Good interfaces gone bad

Lex Spoon lex at cc.gatech.edu
Sat Jun 23 17:17:36 UTC 2001


"Noel J. Bergman" <noel at devtech.com> wrote:
> > it's natural to pop an #asFoo method into String to make converstion
> convenient
> 
> If String>>as<X> was taken any further than it is (and ideally a few of them
> should be moved), it would be a good example of a bad implementation
> pattern.  It increases the surface area of String, coupling it to more and
> more classes.
> 
> Instead, X>>fromString: would serve the exact same purpose, semantically
> represent the encapsulated behavior in the proper place, and leave the
> surface area of String at a minimum.
> 
> For example, could one seriously suggest that "Color fromString: '#FFCCAA'"
> is unclear or inconvenient compared to '#FFCCAA' asColor", or that it would
> be worth polluting the String interface for the perceived convenience, were
> someone so inclined?
> 
> Don't focus too much on String.  String is just an example, inspired by the
> "it's natural" comment above, but the point is that it should not be a
> responsibility of String to convert itself to/from the myriad of other
> objects.  And if something isn't an object's responsibility, it shouldn't be
> in the interface.
> 
> And when did we get away from the notion of responsibility, anyway?
> 


Maybe it shouldn't be the *responsibility* of a string to compute the
represented integer, for example, but on the other hand isn't it natural
for a string to *know* how to do this?  String is widely used to
represent of integers, after all.  In fact, the reason I *like*
Smalltalk, as opposed to merely finding it useful, is that objects have
the common sense that I'd mentally attribute them.  A Point just knows
how to find its distince from the origin.  A string knows how to convert
itself to an integer.

Really, once objects know how to print themselves, it's downhill from
there.  If you think string shouldn't have a conversion to colors, then
why should it have a conversion to a printed representation, either? 
And what about #== -- isn't this a VM feature, which thus should be
somewhere like SystemDictionary?

Overall, I prefer to locate methods by deciding what things an object
would reasonably know how to do.  I want to avoid micromanaging which
class is supposed to perform which operation.  (Though I draw the line
when the convenience leads to ambiguities--e.g., Object>>do:.)  It's
true that I often have the same functionality in two different methods
-- e.g. #asUrl and #absoluteFromText: -- but similarly, if I walk into
an office building and ask the wrong person to help me, they will
frequently forward me to the right person.  I don't think this is a bad
thing.


Now, something I'd agree with is that #asColor should be in a separate
*module* from, say, String>>at:.  #asColor should be in a Color module,
and #asUrl should be in a URL module.  Commercial Smalltalks allow you
to do this, even if Squeak doesn't really support it.


By the way, I have a separate problem with "#asColor": it can mean
different things.  In fact, my first two guesses about it were wrong.  I
guessed that the string would hold either a Color's printString, or a
comma-separated list of *decimal* RGB values.  Instead, it appears to be
decoding HTML's color representation.  Thus, I'd much rather it be
#asColorFromHTML.  Note that integers and URL's don't have this problem,
at least with *my* first guesses about the representation.


And finally, don't knock the convenience of these #asFoo methods. 
Philosophy aside, I'm sure it's the brevity that influences a lot of
people to make and use these methods.

-Lex





More information about the Squeak-dev mailing list