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?
I'm not sure how that relates to the spreadsheet conundrum. Do you expect, in the future, to use phones to dial account numbers? To use phone numbers on calculators? Your example of "future requirements preparedness" is not very good...
Plus, you use the verb "dial". Sure, I could imagine "dialing" an account number on a phone. (It's a big stretch, though.) But if this phone number is to be used on a calculator, would you call the action "dialing"? If the name of the function changes depending on the type of parameter it gets passed, you have a design error.
In a typical OO design, objects get sent messages carrying data, not the other way around.
If your writing OO then you start with the basic object, which is not the number, the number is going INTO the phone, so phone.dial() that way you can also phone.answer() phone.disconnect() phone.powerOFF, ect.
Another way to look at it is does the phone dial the number or does the number dial the phone?
A: phone.dial(phone_number)
The PhoneNumber is dumb and is only a dataset. When the "dialling" happens, should the the PhoneNumber object know how to dial? There are many states to keep track of, like:
If your PhoneNumber object needs to know all this, it's not DRY and your code will be less portable and more likely to break.
I would say that Steven A. Lowe has it down. This should be done by a Controller type object to handle the different states, etc. Keep your PhoneNumber object dumb and give the smarts to the middle-man who needs to worry about keeping the phone humming along.
Neither. The User dials a Phone Number on a Phone.
Clearly, phone.Dial(number)
Clearly the PhoneUserInterface interface, which you can get an implementation of from the PhoneUserFactory.CreatePhoneUser() method, has a method dial(Phone, Number) that you can use to dial the phone.
EDIT: Answering the comment. Neither. The phone should have a buttonPressed() or something like that. The user enters the digits/characters of the phone number via that interface.