This is re-posted from something I posted on the DDD Yahoo! group.
All things being equal, do you write phone.dial(phoneNumber) or phoneNumber.dialOn(phone)? Keep in mind possible future requirements (account numbers in addition to phone numbers, calculators in addition to phones).
The choice tends to illustrate how the idioms of Information Expert, Single Responsibility Principle, and Tell Don’t Ask are at odds with each other.
phoneNumber.dialOn(phone) favors Information Expert and Tell Don’t Ask, while phone.dial(phoneNumber) favors Single Responsibility Principle.
If you are familiar with Ken Pugh’s work in Prefactoring, this is the Spreadsheet Conundrum; do you add rows or columns?
Choosing whether to give the column objects or the row objects the dial method doesn’t change how the program will scale.
The dial method is just going to be itself a sequence of row and column methods. You have to ask what those methods depend on.
If the sequence of row methods doesn’t depend on knowing exactly which column object is involved (but does depend on which particular row object is involved) and vice versa for the sequence of column methods, then the problem scales as m + n (m = num. rows, n = num. cols). When you create a new row it doesn’t actually save you any work had the column method been assigned the ‘dial’ method. You still have to specify a unique sequence of row methods for use in ‘dial’ somewhere!
If, however, say the sequence of column methods inside ‘dial’ doesn’t even depend on which column object is involved (they use one ‘generic’ sequence of column methods), then the problem just scales as m. It doesn’t actually matter if you’ve assigned the ‘dial’ method to the column objects, the program still scales as m; essentially no work is required to make a new dial method when adding 1 more column object and you clearly have the option of abstracting all those dial methods themselves into one generic dial method.