Earlier quoted context omitted.
A simpler example. Should the BankAccount class have a transferTo(BankAccount other) method to transfer money into another account? A BankAccount is a data object, so no processing in there. You could have a Banker object (or a MoneyExchanger object, which is "less real world" solution) which would be the actor object responsible for this task. So the natural message is myBanker.transferMoney(sourceBankAccount, targe…
OO purists actually frown upon the kind of stateless Manager objects you suggest. But I can imagine a scenario in which a money transfer would be something very complex that merits its own process class. I just don't think it makes sense to mandate that kind of heavy weight function class for every operation or be forced to subordinate an operation to an arbitrary class. For instance, formatting a date in Java works…
Yes, but pure OOP has been proven impractical many times over the last 20 years. What we are looking for here are practical rules that will help us organize our code in an OOP framework.
So the date format formats the date. Why is that? Why is date subordinated to date format here?
Actually the name "DateFormat" is unfortunate. It should have been "DateFormatter", because it is clearly an actor object - while a date is a data object. Suppose you have a fire in your house, you want help to extinguish it. So you call a fireman, and you basically say to him "here's a fire : do your job". In the present case you have a date, and you want to format it. So you "call" a DateFormat(ter) and you say "here is a date : do your job". That's exactly the same, natural principle of delegation. If you need something to be done, call an expert to do it for you.
Of course it gets quickly tedious having to explicitly call the actor objects for everything. So it might be useful to add "convenience methods" to the data objects, which would simply call the appropriate default actor and pass themselves as arguments to the work operation. So here you would then be able to call date.format(DateFormat.LONG), which means any date would basically become able to format itself. It has good and bad sides, and there is no clear answer (that I know of) to determine in which cases it's okay to do that or not.
s = format(date, date_format) makes a lot more sense to me
That's because you see formatting as an action, and you're thinking action => function. In an OO environment you should rather be seeing formatting as a responsibility, and thinking responsibility => class.