Clean Code Cheat Sheet Page 2

ADVERTISEMENT

Understandability
Conditionals
From Legacy Code to Clean Code
How to Learn Clean Code
Consistency
+
Encapsulate Conditionals
+
Always have a Running System
+
Pair Programming
+
If you do something a certain way, do all similar things in the same way:
if (this.ShouldBeDeleted(timer)) is preferable to if (timer.HasExpired &&
Change your system in small steps, from a running state to a running state.
Two developers solving a problem together at a single workstation. One is
same variable name for same concepts, same naming pattern for
!timer.IsRecurrent).
the driver, the other is the navigator. The driver is responsible for writing
1) Identify Features
+
corresponding concepts.
the code. The navigator is responsible for keeping the solution aligned with
Positive Conditionals
+
Identify the existing features in your code and prioritise them according to
the architecture, the coding guidelines and looks at where to go next (e.g.
Use Explanatory Variables
+
Positive conditionals are easier to read than negative conditionals.
how relevant they are for future development (likelihood and risk of
which test to write next). Both challenge their ideas and approaches to
Use locals to give steps in algorithms names.
change).
solutions.
Useless Stuff
Encapsulate Boundary Conditions
+
2) Introduce Boundary Interfaces for Testability
+
Commit Reviews
+
Dead Comment, Code
Boundary conditions are hard to keep track of. Put the processing for them
Refactor the boundaries of your system to interfaces so that you can
A developer walks a peer developer through all code changes prior to
Delete unused things. You can find them in your version control system.
in one place, e.g. nextLevel = level + 1;
simulate the environment with test doubles (fakes, mocks, stubs,
committing (or pushing) the changes to the version control system. The
Clutter
simulators).
Prefer Dedicated Value Objects to Primitive Types
+
peer developer checks the code against clean code guidelines and design
Code that is not dead but does not add any functionality
3) Write Feature Acceptance Tests
+
guidelines.
Instead of passing primitive types like strings and integers, use dedicated
Inappropriate Information
primitive types: e.g. AbsolutePath instead of string.
Cover a feature with Acceptance Tests to establish a safety net for
Coding Dojo
+
refactoring.
Comment holding information better held in a different kind of system:
Poorly Written Comment
In a Coding Dojo, a group of developers come together to exercise their
product backlog, source control. Use code comments for technical notes
4) Identify Components
+
skills. Two developers solve a problem (kata) in pair programming. The rest
Comment does not add any value (redundant to code), is not well formed,
only.
observe. After 10 minutes, the group rotates to build a new pair. The
not correct grammar/spelling.
Within a feature, identify the components used to provide the feature.
observers may critique the current solution, but only when all tests are
Prioritise components according to relevance for future development
Maintainability Killers
Obscured Intent
green.
(likelihood and risk of change).
Too dense algorithms that lose all expressiveness.
Duplication
5) Refactor Interfaces between Components
+
Bibliography
Obvious Behaviour Is Unimplemented
Eliminate duplication. Violation of the “Don’t repeat yourself” (DRY)
Refactor (or introduce) interfaces between components so that each
Clean Code: A Handbook of Agile Software Craftsmanship by Robert Martin
principle.
Violations of “the Principle of Least Astonishment”. What you expect is
component can be tested in isolation of its environment.
Magic Numbers / Strings
what you get.
6) Write Component Acceptance Tests
+
Replace Magic Numbers and Strings with named constants to give them a
Hidden Logical Dependency
Cover the features provided by a component with Acceptance Tests.
meaningful name when meaning cannot be derived from the value itself.
A method can only work when invoked correctly depending on something
7) Decide for Each Component:
else in the same class, e.g. a DeleteItem method must only be called if a
Enums (Persistent or Defining Behaviour)
CanDeleteItem method returned true, otherwise it will fail.
Refactor, Reengineer, Keep
+
Use reference codes instead of enums if they have to be persisted. Use
polymorphism instead of enums if they define behaviour.
Decide for each component whether to refactor, reengineer or keep it.
Methods
8a) Refactor Component
+
Exception Handling
Methods Should Do One Thing
+
Redesign classes within the component and refactor step by step (see
Loops, exception handling, …encapsulate in sub-methods.
Catch Specific Exceptions
+
Refactoring Patters). Add unit tests for each newly designed class.
Catch exceptions as specific as possible. Catch only the exceptions for which
Methods Should Descend 1 Level of Abstraction
+
8b) Reengineer Component
+
you can react in a meaningful manner.
The statements within a method should all be written at the same level of
Use ATDD and TDD (see Clean ATDD/TDD cheat sheet) to re-implement the
Catch Where You Can React in a Meaningful Way
+
abstraction, which should be one level below the operation described by
component.
the name of the function.
Only catch exceptions when you can react in a meaningful way. Otherwise,
8c) Keep Component
+
let someone up in the call stack react to it.
Method with Too Many Arguments
If you anticipate only few future changes to a component and the
Use Exceptions instead of Return Codes or null
+
Prefer fewer arguments. Maybe functionality can be outsourced to a
component had few defects in the past, consider keeping it as it is.
dedicated class that holds the information in fields.
In an exceptional case, throw an exception when your method cannot do its
job. Don't accept or return null. Don't return error codes.
Method with Out/Ref Arguments
Refactoring Patterns
Fail Fast
+
Prevent usage. Return complex object holding all values, split into several
Reconcile Differences – Unify Similar Code
+
methods. If your method must change the state of something, have it
Exceptions should be thrown as early as possible after detecting an
Change both pieces of code stepwise until they are identical.
change the state of the object it is called on.
exceptional case. This helps to pinpoint the exact location of the problem by
Isolate Change
+
looking at the stack trace of the exception.
Selector / Flag Arguments
First, isolate the code to be refactored from the rest. Then refactor. Finally,
public int Foo(bool flag)
Using Exceptions for Control Flow
undo isolation.
Split method into several independent methods that can be called from the
Using exceptions for control flow: has bad performance, is hard to
Migrate Data
+
client without the flag.
understand and results in very hard handling of real exceptional cases.
Move from one representation to another by temporary duplication of data
Inappropriate Static
Swallowing Exceptions
structures.
Static method that should be an instance method
Exceptions can be swallowed only if the exceptional case is completely
Temporary Parallel Implementation
+
resolved after leaving the catch block. Otherwise, the system is left in an
Source Code Structure
Refactor by introducing a temporary parallel implementation of an
inconsistent state.
Vertical Separation
+
algorithm. Switch one caller after the other. Remove old solution when no
longer needed.
Variables and methods should be defined close to where they are used.
Legend:
Local variables should be declared just above their first usage and should
Demilitarized Zone for Components
+
have a small vertical scope.
Introduce an internal component boundary and push everything unwanted
DO
+
Nesting
+
outside of the internal boundary into the demilitarized zone between
component interface and internal boundary. Then refactor the component
DON’T
Nested code should be more specific or handle less probable scenarios than
interface to match the internal boundary and eliminate the demilitarized
unnested code.
zone.
Structure Code into Namespaces by Feature
+
Keep everything belonging to the same feature together. Don't use
namespaces communicating layers. A feature may use another feature; a
business feature may use a core feature like logging.
Urs Enzler June2013 V2.1

ADVERTISEMENT

00 votes

Related Articles

Related forms

Related Categories

Parent category: Education
Go
Page of 4