Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)
Rate it:
Open Preview
24%
Flag icon
Affinity might be caused because a group of functions perform a similar operation.
24%
Flag icon
As in newspaper articles, we expect the most important concepts to come first, and we expect them to be expressed with the least amount of polluting detail.
24%
Flag icon
We use horizontal white space to associate things that are strongly related and disassociate things that are more weakly related.
25%
Flag icon
A source file is a hierarchy rather like an outline.
26%
Flag icon
A team of developers should agree upon a single formatting style, and then every member of that team should use that style.
26%
Flag icon
And yet the interface still unmistakably represents a data structure.
26%
Flag icon
But it represents more than just a data structure.
26%
Flag icon
Hiding implementation is not just a matter of putting a layer of functions between the variables.
26%
Flag icon
A class does not simply push its variables out through getters and setters.
26%
Flag icon
Rather it exposes abstract interfaces that allow its users to manipulate the essence of the data, without hav...
This highlight has been truncated due to consecutive passage length restrictions.
26%
Flag icon
We do not want to expose the details of our data. Rather we want to express our data in abstract terms.
26%
Flag icon
Serious thought needs to be put into the best way to represent the data that an object contains. The worst option is to blithely add getters and setters.
26%
Flag icon
Objects hide their data behind abstractions and expose functions that operate on that data.
26%
Flag icon
Data structure expose their data and have no meaningful functions.
26%
Flag icon
The shape classes are simple data structures without any behavior.
27%
Flag icon
Consider what would happen if a perimeter() function were added to Geometry.
27%
Flag icon
On the other hand, if I add a new shape, I must change all the functions in Geometry to deal with it.
27%
Flag icon
So if I add a new shape, none of the existing functions are affected, but if I add a new function all of the shapes must be changed!1
27%
Flag icon
Procedural code (code using data structures) makes it easy to add new functions without changing the existing data structures.
27%
Flag icon
OO code, on the other hand, makes it easy to add new classes without changing existing functions.
27%
Flag icon
Procedural code makes it hard to add new data structures because all the functions must change.
27%
Flag icon
OO code makes it hard to add new functions because all the classes must change.
27%
Flag icon
So, the things that are hard for OO are easy for procedures, and the things that are hard for...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
In any complex system there are going to be times when we want to add new data types ...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
For these cases objects and OO are mos...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
On the other hand, there will also be times when we’ll want to add new functions ...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
In that case procedural code and data structures will be...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
There is a well-known heuristic called the Law of Demeter2 that says a module should not know about the innards of the objects it manipulates.
27%
Flag icon
More precisely, the Law of Demeter says that a method f of a class C should only call the methods of these:
27%
Flag icon
C
27%
Flag icon
An object crea...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
An object passed as an ar...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
An object held in an instance v...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
The method should not invoke methods on objects that are returned by any of...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
In other words, talk to friends, not ...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
The following code3 appears to violate the Law of Demeter (among other things) because it calls the getScratchDir() function on the return value of getOptions() and then calls getAbso...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
This kind of code is often called a train wreck because it look like a bunch of coupled train cars.
27%
Flag icon
Whether this is a violation of Demeter depends on whether or not ctxt, Options, and ScratchDir are objects or data structures.
27%
Flag icon
If they are objects, then their internal structure should be hidden rather than exposed, and so knowledge of their innards is a clear violation of the Law of Demeter.
27%
Flag icon
On the other hand, if ctxt, Options, and ScratchDir are just data structures with no behavior, then they naturally expose their internal st...
This highlight has been truncated due to consecutive passage length restrictions.
27%
Flag icon
This issue would be a lot less confusing if data structures simply had public variables and no functions, whereas objects had private variables and public functions.
27%
Flag icon
However, there are frameworks and standards (e.g., “beans”) that demand that even simple data structures have accessors and mutators.
27%
Flag icon
Such hybrids make it hard to add new functions but also make it hard to add new data structures.
27%
Flag icon
What if ctxt, options, and scratchDir are objects with real behavior?
27%
Flag icon
Then, because objects are supposed to hide their internal structure, we should not be able to navigate through them.
27%
Flag icon
If ctxt is an object, we should be telling it to do something; we should not be asking it about its internals.
28%
Flag icon
Ignoring that, however, we see that the intent of getting the absolute path of the scratch directory was to create a scratch file of a given name.
28%
Flag icon
So, what if we told the ctxt object to do this?
28%
Flag icon
BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
28%
Flag icon
The quintessential form of a data structure is a class with public variables and no functions.