All you need is rows and columns...
Clemens Vasters issued a small shot across the bows: http://staff.newtelligence.net/clemensv/PermaLink.aspx?guid=8a119c62-2fc1-4409-9ae4-0b250fdb785b Jimmy Nilsson offered a response at http://www.jnsk.se/weblog/posts/toclemens.htm While I have been moving away from the idea of a domain model as a desired first approach to development for some time, I think Clemens arguments are a bit weak in this case. Not because they are wrong, but because the example listed is kind of weak (the fruit was hanging too low) and because he equates the idea of having to strongly type and validate every attribute as the natural result of OOA. The idea that the each address class would have to format themselves for every use case is also pretty ugly conclusion to come to.
Nevertheless, the opening statement is closer to the real nugget in his blog, "show me where inheritance and full data encapsulation make sense on the business domain". So, when everybody is sick to death of this argument, why enter bother? Because you still have accomplish the goals of validation, persistence and code reuse, whichever style you choose, and between the choices compared, neither is very satisfactory. Clemens argument that the sort of validation you can do when you access a property setter is almost useless is right on. Type checking, that's good. Range checking, good. But so much validation requires knowledge of other attributes, context and so on that for the most part the validation you can do at property set time is unable to accomplish much of any use. So, as he points out, you end up with address.Validate(); and to which he says it's a small step to SomeStaticUseCaseSpecificClass.Validate(address); Actually that is a huge step.
In his example, the address was created somewhere, and more specifically, an address is created in the context in which it is used. Some of the logic in Address might be possible with just the the address class: must have city and state to save. More might be possible only with help from another domain class, say CityStateReference, still under the control of the Address class. Still more might be related to the user accessing the class, such as role specific logic: a user can read an address, an administrator can delete only, a marketinggod can CRUD. Other logic can be very use case specific: an address is a match if the name matches exactly for a credit card purchase, but fuzzy matching algorithms are to be used for sending out the weekly newsletter.
The use case is the context and only in context can the correct logic be assembled. You must assemble that logic somewhere. IMHO, a domain model cannot be properly setup without input from the use case. It is correct to say that a standalone Address class completely constructible from new Address() or new Address(int id) would be pretty hard to justify. If on the other hand the domain model can build the address based on input from the use case, Strategy can be used to supply it with the correct logic needed at runtime. And while design of the factory/builder/abstract factory can be a challenge, I have lived through the twisted, unreadable alternatives that procedural style calls require, with it's pages of if/else trees and switch statements, and gosh darn, I choose OO techniques ;-)
As in Jimmy's comments, I don't use inheritance much except where there is little chance of the scope of context creeping in and influencing the design of the inheritance tree. From years of XML work, software design, company org charts and other exercises in hierarchal futility, I think single rooted trees only work in the simplest cases. Avoid 95% of the time.
AOP takes another spin on the idea of composition of instances to create the correct logic at runtime. What AOP and a more enlightened domain model would have in common would be in invocation framework that does more than “new” can give you. It also allows you to design the overarching goal of saying “an address can be created, read, updated or deleted, validate itself, and evaluate name matches” and not have that simple story, or choice of domain method names, mucked up by 20 different use cases with special conditions.
So, rather than say that in practice, OO is not useful in the business domain, I think you have to expand your vision of OO. It's just that 1995 style, inheritance driven, property setter challenged version of OO, which seems to be what the overwhelming majority of developers think OO is, that is not useful in business domains.