TDD and System Architecture

When first adopting TDD, developers can run into some roadblocks that seem to indicate that TDD is a difficult process. In truth, some of these problems actually indicate faults in the system architecture.

For example, developers will struggle to write unit tests of behavior that is embedded in a user interface, or in stored procedures in a database. Allowing a test to “push a button” in a UI involves the user of complex tools and tends to slow down the test execution. The same is true if the test has to spin up the database. Continue reading “TDD and System Architecture”

TDD Yields Velocity

When TDD was first suggested, there were many who were dubious about the wisdom of having developers write tests of their own code. Among the objections raised was that developers will slow down if you burden them with new tasks, namely writing the tests as well as the code.

This seems logical. Give someone more to do, and they will take longer to do it. But the truth is that TDD actually increases velocity once the team gets over the initial learning curve.

How can this be? This is true for three reasons. Continue reading “TDD Yields Velocity”

TDD Yields Confidence

TDD is a process that provides constant confirmation to the development team.

Writing the tests up-front confirms that there is sufficient understanding of requirements so that they can be expressed in the rigorous form of a unit test. Alternately, it reveals that this understanding has gaps and reveals questions that need to be answered.

The quality of the test mirrors the quality of the system, and so if “good” tests (as I have defined them) can be written, this is confirmation of a good design. Continue reading “TDD Yields Confidence”

Going Beyond Design Patterns

This was originally published August 2012

In our Design Patterns Thinking  course we quote Christopher Alexander’s Timeless Way of Building – the book that inspired the software development community to create design patterns. Most everyone familiar with design patterns is familiar with Alexander’s phrase “patterns are solutions to recurring problems in a context.” However, my favorite quote of Alexander is 4 pages from the end of his 549 page book –”At this final stage, the patterns are no longer important: the patterns have taught you to be receptive to what is real.”

For those new to patterns, these two quotes may seem contradictory, but to readers of his book and attendees at our course, the typical response is “yes, I already knew that.” Design patterns are solutions to a design problem in the way recipes are solutions to a “what do I want to eat?” problem. Learning design patterns as solutions to recurring problems in a context in order to be a great designer is like learning how to be a great chef by learning recipes. While useful to a degree, it is not very effective to become a master.

We need to remind ourselves that patterns are examples of solutions given a particular set of issues to be dealt with. The Gang of Four’s set of 23 patterns provides a meta-pattern that can teach us how to handle variations in a problem domain. Our Design Pattern Repository lists patterns by what they encapsulate. This is an extremely important insight. In both Agile and non-Agile teams, requirements will change – the biggest differences are: rate of change, size of change, and how we prepare our code for the change.

Most new requirements change in how a concept is to be implemented more as opposed to a totally new concept emerging. Code is often written as “this is the way it’ll work” and therefore is not well prepared for when a new, different way comes along. When we truly understand the thought process of patterns, they will provide us with a different way of looking at the world. I discussed this in my article Can Patterns Be Harmful? as well as my book Design Patterns Explained: A New Perspective on Object-Oriented Design. In other words, patterns don’t just provide us with good solutions, they can provide us with a thought process in which to achieve quality solutions to unique situations for which no current pattern exists.

The focus on patterns as solutions is unfortunate. The insistence that patterns are discovered, instead of created, obscures the fact that there is a thought process underneath these patterns. This thought process is worth discovering.  One aspect of this thought process is how to refactor code using the knowledge of patterns – something called “refactoring to patterns.” I introduced this concept in our first design patterns class in 1999 (as well as my aforementioned book). It provides a basis for refactoring quality code as needed using the thought process of patterns. You can learn more about this in the Refactor To The Open Closed chapter in our Essential Skills for the Agile Developer: A Guide to Better Programming and Design book. This is also discussed in the Avoid Over and Under Design chapter the same book. If you prefer webinars, watch Avoiding Over and Under Design in Agile Projects.

If you want to learn more, the best place is to take one of our Design Patterns classes. We currently have one scheduled in Seattle – Design Patterns for the Agile Developer, October 30- November 1. If you are in another city and have 4 or more folks interested, please contact Mike Shalloway (mike.shalloway@netobjectives.com) and we’ll see if we can schedule a course near you.

 

Shalloway’s Law and Shalloway’s Principle

This blog was first written in August 2007

A few years ago somebody came up to me in one of my classes and said, “you’re the CEO of a successful company, co-author of a successful book (Design Patterns Explained: A New Perspective on Object-Oriented Design), … you ought to have something named after yourself.” So I, of course, immediately like this guy and think – hmm, what should that be?  I came up with this:

Shalloway’s Law:

“When N things need to change and N>1, Shalloway will find at most N-1 of these things.”

Hey, I didn’t say it was complimentary. It’s a law! I have to follow it. That’s the problem. BTW: They didn’t ask me about gravity either when I was born! I really would like to break that law at times too!

Eventually I came up with Shalloway’s Principle:

“Avoid situations w

Hey, I didn’t say it was complimentary. It’s a law! I have to follow it. That’s the problem. BTW: They didn’t ask me about gravity either when I was born! I really would like to break that law at times too!

So I came up with Shalloway’s Principle:

“Avoid situations where Shalloway’s Law applies”

Shaloway’s law applied when “N > 1″ and Shalloway has to find all of the things involved. In other words, avoid redundancy (make N=1) or make it so Shalloway doesn’t have to find the things. For example, I may have redundancy in my interfaces. But I also have a cool “to do list generator” (some people call it a compiler) that when I change a method’s interface it tells me what I need to update. Better not to have redundancy at all, but if you do, make sure Shalloway’s law does not apply.

For an in depth view of this, see Shalloway’s Law and Shalloway’s Principle from Essential Skills for the Agile Developer: A Guide to Better Programming and Design.

Specifying Exceptions in TDD

Exceptions in software represent a mechanism for raising an alarm when something goes wrong. They are used when there is a potential problem that cannot be detected by the compiler, linker, or other automated aspect of the development process, and thus may potentially make it into the released product.

When an exception is declared in the code, it is basically a way of saying, “We hope this never happens, but if it does at least we’ll be made aware of it.” Getting the exception is bad news, but the problem that caused it is made visible so we can deal with it. Not getting the exception is good news. Everything is fine.

In TDD, however, this is logically reversed. Continue reading “Specifying Exceptions in TDD”

Specifying Workflows in TDD, Part 2: How

Specifying a workflow in #TDD means writing a test that says, “When entity A is called upon to accomplish a task, it must interact with entity B is the following way.” This is done when the interaction in question is part of a required workflow, and not simply an implementation decision that should be changeable.

The best way to accomplish this is to create a mock of entity B. Such a mock would “log” how it is used by entity A at test time, and then allow the test to examine the log and compare it to what should have happened. There are many ways to accomplish this. Continue reading “Specifying Workflows in TDD, Part 2: How”

Specifying Workflows in TDD, Part 1: Why

The term “workflow” in this sense is meant to indicate the way two system elements interact when performing a task. Often these interactions themselves are not exposed outside the system, and so only their resulting behavior should be tested. This is as true in TDD as it is in traditional testing.

Most workflows are implementation details that developers should be able to change so long as the right behavior is still achieved. If the developers have a better idea, or technology improves, these changes should not break tests. Continue reading “Specifying Workflows in TDD, Part 1: Why”

Specifying Boundaries in TDD: Part 2

Recently I wrote about the necessity in TDD of specifying both sides of a behavioral boundary, and its epsilon. This is important because we want a complete, detailed record of the critical business rules and other values in the system.

But there is another reason that this is important. It has to do with the notion of “a specification.” Continue reading “Specifying Boundaries in TDD: Part 2”