views:

800

answers:

3

It is probably just me, which is why I'm asking the question. Information Expert, Tell Don't Ask, and SRP are often mentioned together as best practices. But I think they are at odds. Here is what I'm talking about:

Code that favors SRP but violates Tell Don't Ask, Info Expert:

Customer bob = ...;
// TransferObjectFactory has to use Customer's accessors to do its work, 
// violates Tell Don't Ask
CustomerDTO dto = TransferObjectFactory.createFrom(bob);

Code that favors Tell Don't Ask / Info Expert but violates SRP:

Customer bob = ...;
// Now Customer is doing more than just representing the domain concept of Customer,
// violates SRP
CustomerDTO dto = bob.toDTO();

If they are indeed at odds, that's a vindication of my OCD. Otherwise, please fill me in on how these practices can co-exist peacefully. Thank you.

Edit: someone wants a definition of the terms -

Information Expert: objects that have the data needed for the operation should host the operation

Tell Don't Ask: don't ask objects for data in order to do work; tell the objects to do the work

Single Responsibility Principle: each object should have a narrowly defined responsibility

+4  A: 

I don't think that they are so much at odds as they are emphasizing different things that will cause you pain. One is about structuring code to make it clear where particular responsibilities are and reducing coupling, the other is about reducing the reasons to modify a class.

We all have to make decisions each and every day about how to structure code and what dependencies we are willing to introduce into designs.

We have built up a lot of useful guidelines, maxims and patterns that can help us to make the decisions.

Each of these is useful to detect different kinds of problems that could be present in our designs. For any specific problem that you may be looking at there will be a sweet spot somewhere.

The different guidelines do contradict each other. Just applying every piece of guidance you have heard or read will not make your design better.

For the specific problem you are looking at today you need to decide what the most important factors that are likely to cause you pain are.

Hamish Smith
so, _all_ SOLID principles at least in some cases cannot be satisfied simultaneously -- i.e. may harm and are not "the more of all of them the better" metrics :)
mlvljr
+1  A: 

Those classes are not at odds. The DTO is simply serving as a conduit of data from storage that is intended to be used as a dumb container. It certainly doesn't violate the SRP.

On the other hand the .toDTO method is questionable -- why should Customer have this responsibility? For "purity's" sake I would have another class who's job it was to create DTOs from business objects like Customer.

Don't forget these principles are principles, and when you can et away with simpler solutions until changing requirements force the issue, then do so. Needless complexity is definitely something to avoid.

I highly recommend, BTW, Robert C. Martin's Agile Patterns, Practices and principles for much more in depth treatments of this subject.

Phil Bennett
+1  A: 

You can talk about "Tell Don't Ask" when you ask for object's state in order to tell object to do something.

In your first example TransferObjectFactory.createFrom just a converter. It doesn't tell Customer object to do something after inspecting it's state.

I think first example is correct.

vsevolod_p