Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))
Nat Pryceamazon.com
Growing Object-Oriented Software, Guided by Tests (Addison-Wesley Signature Series (Beck))
When we notice that a group of values are always used together, we take that as a suggestion that there’s a missing construct.
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.”
Break up an object if it becomes too large to test easily, or if its test failures become difficult to interpret. Then unit-test the new parts separately.
Driving an interface from its client avoids leaking excess information about its implementers, which minimizes any implicit coupling between objects
We value code that is easy to maintain over code that is easy to write.1 Implementing a feature in the most direct way can damage the maintainability of the system, for example by making the code difficult to understand or by introducing hidden dependencies between components.
Objects can break encapsulation by sharing references to mutable objects, an effect known as aliasing.
The fewer methods there are on an interface, the more obvious is its role in the calling object.
Wherever possible, an acceptance test should exercise the system end-to-end without directly calling its internal code. An end-to-end test interacts with the system only from the outside: through its user interface, by sending messages as if from third-party systems, by invoking its web services, by parsing reports, and so on.