Skip to content

Instantly share code, notes, and snippets.

@liammclennan
Created January 27, 2011 05:57
Show Gist options
  • Save liammclennan/798133 to your computer and use it in GitHub Desktop.
Save liammclennan/798133 to your computer and use it in GitHub Desktop.
tell-don't-ask vs. no external dependencies on domain objects
// tell don't ask means I might do something like this
var folder = new Folder("foo");
folder.Delete();
// but for that to work the folder class needs to depend on a file IO service (to do the deleting).
// the alternative is procedural
public class FolderService
{
public FolderService(IFileSystem fileSystem) {...}
public void Bar()
{
var folder = new Folder("foo");
fileSystem.Delete(folder.Path); // here is the tell-dont-ask violation
}
}
// what is the right way to do this?
@flq
Copy link

flq commented Jan 27, 2011

depending on your requirement you could use a message in wherever it is decided to notify the outside world that a deletion is required

bus.Publish(new RequestForDeletionOfFolder("foo"));

@liammclennan
Copy link
Author

Interesting idea. In this case each domain class would have a dependency on an event aggregator.

It violates my requirement to not take dependencies, but it also reduces the set of dependencies to one.

One of the reasons I don't want domain classes to have dependencies is to facilitate testing. If they need access to an event aggregator that means that every time I create a Folder (or any other domain class) object I have to give it a reference to the aggregator, or the aggregator has to be static. A static aggregator might work well because when testing there would be no registered listeners so nothing happens.

@mleech
Copy link

mleech commented Jan 27, 2011

There are parallels here with normal DB related CRUD. "Folder" = domain object, "file system" = DB.
What about using the Repository pattery?
"folder.Delete();" is more like active record.

@flq
Copy link

flq commented Jan 27, 2011

If you look at posts e.g. from Udi Dahan about Domain Events, the Domain objects do have a possibility to raise events (messages, whatever). It also lends itself well to a certain kind of blackbox testing. If you use some kind of event aggregator (I prefer to think of it as Bus) in your test you can assert whether certain messages/events have been generated by the parts of the domain under test.

@harukizaemon
Copy link

FWIW, I've build a number of large systems using Event Sourcing - I'm giving a talk next week as it happens - and I would never go back to using anything else. Testing is a breeze.

@liammclennan
Copy link
Author

Thanks everyone. Udi talks about Domain Events at http://www.udidahan.com/2009/06/14/domain-events-salvation/. Domain Events appear to be an elegant partial solution to the original problem. I say partial because an external dependency is still required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment