Listen to this post
One aspect of strong design is that separation is created between the various concerns of the system. This adds clarity, promotes re-use, improves cohesion, and in general adds value to the work.
It can be difficult to know, however, if one has separated things sufficiently, or perhaps has overdone it. This is one area where TDD can help.
Example: An object with asynchronous behavior has, at minimum, two categories of concerns.
- The main behavior the object is responsible for delivering to the system.
- The thread-safety of that behavior, that it is re-entrant or that it properly prevents race conditions, etc.
Normally a developer would simply use the provided mutex that the framework supplies to ensure the behavior was thread-safe, and this would be part of the implementation of the main behavior. However, when trying to test that safety, it is quite difficult to simulate threading problems to ensure that the right actions are taken.
This leads to a separation of these concerns, using a Design Pattern called the Synch Proxy. This makes the testing much easier, but also yields the healthy separation of concerns that good design should reflect.
Thus, TDD is also Test-Driven Design.