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))
The API of a composite object should not be more complicated than that of any of its components.
When we want to mark a new domain concept in the code, we often introduce a placeholder type that wraps a single field, or maybe has no fields at all. As the code grows, we fill in more detail in the new type by adding fields and methods. With each type that we add, we’re raising the level of abstraction of the code.
When we notice that a group of values are always used together, we take that as a suggestion that there’s a missing construct.
When extracting implicit components, we start by looking for two conditions: arguments that are always used together in the class, and those that have the same lifetime. Once we’ve found a coincidence, we have the harder task of finding a good name that explains the concept.
Driving an interface from its client avoids leaking excess information about its implementers, which minimizes any implicit coupling between objects
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.
an interface describes whether two components will fit together, while a protocol describes whether they will work together.
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.