Along time ago, I was introduced to the "demeter metric." At the time it was summed up to me as chained message sends. For example:
(self components at: 4) container container topComponent model keyboardProcessor actions first id
No, it's not a real code example. It doesn't work. Just something I cooked up. But it's reminiscient of fragments we've all seen from time to time. In general, this kind of thing is not good. It's like a long chain, and with so many links, the likelihood that a change in one of them will cause it to all crash down increases. In short, too much coupling.
Of late, I've come to appreciate another form of coupling. Messages with too many arguments. When we concoct a message with multiple arguments, we're saying this object needs this arguments all at the same time. Often, it's just shortcut stuff. The problem is that when you want to change the interface to that object, you have to weave your new argument in with all of these big many argument message. Try refactoring or enhancing the interface to Dialog and you'll discover just what a pain this is. IMO, it's far better when possible to break all of this setters up into separate pieces and invoke them separately as needed. When we do this, we're able to actually make more and richer use fo the objects we interface with.
For fun, I put together a script that finds the highest number of arguments in an image:
| count winners |
count := 0.
winners := Set new.
Smalltalk allBehaviorsDo:
[:eachBehav |
eachBehav selectors do:
[:each |
myCount := each numArgs.
myCount = count ifTrue: [winners add: each].
myCount > count
ifTrue:
[count := myCount.
winners := Set with: each]]].
winners
The winner in the VisualWorks development image appears to be this monster:
IndentedLabelAndIcon>>
newIndentLevel:
hasChildren:
hasParent:
isExpanded:
isFirst:
isLast:
rootIcon:
trailingIcon:
icon:
offset:
withTextOrString:
withAttibutes:
displayableIndents:
view:
index:
lookType:
Can anyone beat that?