Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))
amazon.com
Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))

Driving an interface from its client avoids leaking excess information about its implementers, which minimizes any implicit coupling between objects
Never write new functionality without a failing test.
The API of a composite object should not be more complicated than that of any of its components.
Objects can break encapsulation by sharing references to mutable objects, an effect known as aliasing.
When we notice that a group of values are always used together, we take that as a suggestion that there’s a missing construct.
an interface describes whether two components will fit together, while a protocol describes whether they will work together.
Loosely speaking, we use the message-passing style we’ve just described between objects, but we tend to use a more functional style within an object, building up behavior from methods and values that have no side effects.
As John Gall wrote in [Gall03], “A complex system that works is invariably found to have evolved from a simple system that works.”
One of the symptoms of an unstable development environment is that there’s no obvious first place to look when something fails.