Too Many Open Files, Or Too Few Bounded Contexts?

A Business Men Climbing a Pile of PapersServer software needs to run unsupervised for long periods of time to be practical.

Release It! is full of horror stories about programming mistakes that get in the way of that lofty goal.

One example is opening files and forgetting to close them.

On some operating systems this will eventually lead to a Too many open files error when the number of open files passes a certain limit.

Of course we want to make sure that doesn’t happen to us. IDEs like Eclipse can give you warnings in certain cases to help with that, but if you’re test infected like me, you will want to write a test to make sure.

This is one of those situations where people less committed to (unit) testing tend to give up. There is nothing in the Java file system API that tells you how many files are open, so it simply cannot be done, right?

Not so fast, my friend!

First, with some proprietary code you can, in fact, count the number of open files in Java.

Second, we can do even better if we step back for a moment and take a look at the bigger picture. Chances are that our application isn’t really about files; that using files is simply a convenient implementation choice.

In the lingo of Eric Evans’ classic Domain-Driven Design, we have (at least) two bounded contexts: your core domain (what people buy/use your application for) and the file system.

A bounded context delimits the applicability of a particular model so that team members have a clear and shared understanding of what has to be consistent and how it relates to other contexts.

Evans describes a number of strategies for dealing with different bounded contexts. In our example, the file system API is not under our control, which rules out the majority of them. The remaining strategies are:

  • Separate Ways, i.e. use something other than the file system. That probably doesn’t make sense in this example
  • Conformist, i.e. follow the Java model slavishly. This is what most developers do without giving it much thought
  • Anti-Corruption Layer, i.e. create an isolating layer to provide clients with functionality in terms of their own domain model. This layer translates in both directions as necessary between the two models

This last strategy gives us more than “just” the opportunity to keep our models clear and to the point. By introducing interfaces that we control in our anti-corruption layer, we also gain the opportunity to mock those interfaces in our tests, making it very easy to verify that we indeed close all the files we open.

This is yet another example where difficulty in unit testing a piece of code points to an opportunity to improve the design. If we consistently act on such opportunities, we will end up with a clean architecture that is a joy to work with.

Brian Marick: I think I finally understand mocks

Yesterday I attended a meeting co-organized by Devnology and Agile Holland and hosted by the Dutch eBay where Brian Marick talked about mocks.

Brian started out with a visual demonstration of what object oriented programming is all about: interaction between objects. Each object doesn’t do very much by itself, but it’s the complex web of interacting objects that gets the job done. He visualized this interaction by having “volunteers” (representing objects) passing around a little ball (representing the flow of control):
Visual Demonstration of Object Interactions

He then went on to introduce interaction based testing using mock objects. This approach is a really white form of white box testing, since it not only knows about objects and their methods, but also about how these methods are implemented, i.e. what other objects they call and how.

Interaction based testing lends itself naturally to a top-down approach of TDD. This maximizes the chance that the objects that are designed into existence by the tests fit seamlessly with the objects calling them.

Brian described some other differences between interaction based (“London school”) and the more traditional state based (“Detroit school”) of TDD. Both have pros and cons, but ultimately Brian feels that interaction based testing using mocks makes it more likely to work with ease.
Work with Ease