McCabe Complexity and Design
Another in the Enerjy TV series. This time, the question is “How do you believe McCabe Complexity helps programmers?”
Is excellent design "too Eastern" for us?
I have spent the last two days with Mary and Tom Poppendieck at one of their Practitioners Courses, and I find myself inspired. Among the interesting moments for me was a point at which I reached an unsettling notion: are we “too Western” to design software well?
I came to this question while watching course attendees talk about the problems in their organization. As they explored the flow of value through their IT organizations, I kept hearing about managers interrupting the flow and of centralized decision-makers as bottlenecks, when it occurred to me: I’ve heard about these problems in code before.
Specifically, I heard the word “manager” and my mind wandered towards thinking of Manager classes in a code base, rather than flesh-and-blood managers. In that wandering instant I saw a connection between the two kinds of managers: human managers have mostly commonly been trained over the last century to micro-manage, make important decisions and direct their people; and Manager classes do essentially the same thing in code. Now, while our ideas of management have changed in the past 50 years, mostly due to the work coming out of Toyota, we are still over-run by micro-managers whose effectiveness is limited.
It’s quite similar with code. In spite of the object-oriented design movement and the advance of test-driven development with its emphasis on simple design, procedural thinking dominates, even in code bases that use object-oriented languages. Most programmers approach code with Procedural Mind, even when they believe they want to design with objects. Even when I teach people how their can arrive at excellent designs by following four simple rules, Procedural Mind dominates.
So I wonder: given the parallels between tactical, command-and-control management and highly procedural code where important decisions are centralized in these Manager classes, and given that our most common human management style is a relic of western military thinking, and given that it perpetuates in part due to culturally-entrenched ideas about managing people, are Western programmers conditioned against excellent design? Are we mostly doomed to gather our code in Manager classes, rather than distribute responsibilities evenly and focus on object interaction?
Are those notions simply too Eastern for us?
Stub your worries away
I recently came across this question on the testdrivendevelopment Yahoo! group.
Hi everyone,I’d like some advice/opinions on how to test some existing code. It’s a web application using Spring and struts.
I have a class called the ProcessedFilesManager which contains a number of methods used by Struts Action classes. This manager communicates with five different DAOs to get the information that some of the Struts actions are interested in. Now, I want to test this manager class (ProcessedFilesManager). The way I’ve started doing it is stubbing up each of the five DAOs, however, this is proving to be quite painful. I didn’t want to use a mocking approach, nor did I want to use a DB solution like Hypersonic, but now I’m open to suggestions.
Seeing as there a number of approaches I could use, what do you think would be best for this situation?
It feels wrong to stub the DAOs because what if I’m introducing behaviour in there that differs from the actual DAOs? My tests will not be accurate.
Any advice/comments would be much appreciated.
[Read the thread]
I used to have this fear, and I do something now that has eliminated that fear.
When I stub a DAO method, I make an assumption about what that DAO method does. I used to be worried about making the wrong assumption, but now I have a contract test for the DAO interface that tests for the assumption I’m making in my Service test. The contract test gives me confidence that any implementation of the DAO method passes the same tests, so every implementation of that DAO method behaves the way I assume it does. Once I have this, I feel comfortable stubbing that DAO method that way in a Service test.
A contract test is a test for an interface. I describe contract tests in some detail in JUnit Recipes, recipe 2.6, although back then I called them “abstract test cases” because I hadn’t yet discovered the better name “contract test”. If you prefer, I’ve provided a diagram showing some contract tests for a typical DAO class.

Since classes inherit methods from their superclasses, the Hibernate Customer DAO Test will inherit the contract tests from its superclass, as will the JDBC Customer DAO Test. This means that each implementation has to pass not only its own tests (like testClosesSession() or testClosesResultSet()) but also the tests inherited from Customer DAO Contract Test Template. (I call it a “template” because it plays the role of template in the Template Method design pattern.) When you test-drive a new implementation of Customer DAO, simply make the new test extend the contract test template and you’ll automatically inherit its contract tests. This way, I have confidence that any implementation of Customer DAO behaves the way I’d expect any Customer DAO to behave.
Returning to our example, these contract tests give me confidence to stub the DAO when I test-drive the Service, and that confidence brings with it a happy side effect. I am confident that findAllWithPendingOrders() only returns customers with pending orders, so I don’t have to worry about that issue at all when I design the Service that reports all customers with pending orders. Now that I notice it, Report All Customers With Pending Orders Service is really just a Report on Customers Service that needs a Customer Filter, which could be a Pending Orders Customer Filter. I don’t think I would have felt comfortable with this level of generalization if I weren’t so confident in the way I’ve separated the responsibilities.
The next time you want to avoid stubbing a method because you’re worried you’ll make a wrong assumption about what the method does, try writing enough contract tests to give you the confidence you need. I think you’ll like the results.
Dynamic test doubles and brittle tests
Just a quick one. I’ll write the proof later.
People commonly complain to me that when they try to test-drive code with test doubles (say with JMock), they end up with brittle tests: when the code changes, all these tests change. I understand, because it used to be that way for me, too. Nowadays, it doesn’t cause me a problem, and I believe it’s because my interfaces tend to stabilize quickly, and I believe that happens because my interfaces tend to be minimal with appropriately-distributed behaviors. How did I get to design so well?
When JMock told me my tests were brittle, I changed my design so that the tests were more robust. The result, as a side effect, was smaller, more cohesive interfaces and less coupling between classes and their collaborators.


