Principles
|
Loose Coupling •
High Cohesion •
Change is Local •
It is Easy to Remove
|
Smells
|
Rigidity •
Fragility •
Immobility •
Viscosity of Design •
Viscosity of Environment •
Needless Complexity •
Needless Repetition •
Opacity
|
Class Design
|
|
Package Cohesion
|
Release Reuse Equivalency Principle (RREP) •
Common Closure Principle (CCP) •
Common Reuse Principle (CRP)
|
Package Coupling
|
Acyclic Dependencies Principle (ADP) •
Stable Dependencies Principle (SDP) •
Stable Abstractions Principle (SAP)
|
General
|
Follow Standard Conventions •
Keep it Simple, Stupid (KISS) •
Boy Scout Rule •
Root Cause Analysis
Multiple Languages in One Source File
|
Environment
|
Project Build Requires Only One Step •
Executing Tests Requires Only One Step •
Source Control System •
Continuous Integration
Overridden Safeties
|
Dependency Injection
|
Decouple Construction from Runtime
|
Design
|
Keep Configurable Data at High Levels •
Don’t Be Arbitrary • Be Precise •
Structure over Convention •
Prefer Polymorphism To If/Else or Switch/Case •
Symmetry / Analogy •
Separate Multi-Threading Code
Misplaced Responsibility •
Code at Wrong Level of Abstraction •
Fields Not Defining State •
Over Configurability •
Micro Layers
|
Dependencies
|
Make Logical Dependencies Physical
Singletons / Service Locator •
Base Classes Depending On Their Derivatives •
Too Much Information •
Feature Envy •
Artificial Coupling •
Hidden Temporal Coupling •
Transitive Navigation
|
Naming
|
Choose Descriptive / Unambiguous Names •
Choose Names at Appropriate Level of Abstraction •
Name Interfaces After Functionality They Abstract •
Name Classes After How They Implement Their Interfaces •
Name Methods After What They Do •
Use Long Names for Long Scopes •
Names Describe Side Effects •
Standard Nomenclature Where Possible
Encodings in Names
|
Understandability
|
Consistency •
Use Explanatory Variables •
Encapsulate Boundary Conditions •
Prefer Dedicated Value Objects to Primitive Types
Poorly Written Comment •
Obscured Intent •
Obvious Behaviour Is Unimplemented •
Hidden Logical Dependency
|
Methods
|
Methods Should Do One Thing •
Methods Should Descend 1 Level of Abstraction
Method with Too Many Arguments •
Method with Out/Ref Arguments •
Selector/Flag Arguments •
Inappropriate Static
|
Source Code Structure
|
Vertical Separation •
Nesting •
Structure Code into Namespaces by Feature
|
Conditionals
|
Encapsulate Conditionals •
Positive Conditionals
|
Useless Stuff
|
Dead Comment, Code •
Clutter •
Inappropriate Information
|
Maintainability Killers
|
Duplication •
Magic Numbers / Strings •
Enums (Persistent or Defining Behaviour)
|
Exception Handling
|
Catch Specific Exceptions •
Catch Where You Can React in a Meaningful Way •
Use Exceptions instead of Return Codes or null •
Fail Fast
Using Exceptions for Control Flow •
Swallowing Exceptions
|
From Legacy Code to Clean Code
|
Always have a Running System •
1) Identify Features •
2) Introduce Boundary Interfaces for Testability •
3) Write Feature Acceptance Tests •
4) Identify Components •
5) Refactor Interfaces between Components •
6) Write Component Acceptance Tests •
7) Decide for Each Component: Refactor, Reengineer, Keep •
8a) Refactor Component •
8b) Reengineer Component •
8c) Keep Component
|
Refactoring Patterns
|
Reconcile Differences – Unify Similar Code •
Isolate Change •
Migrate Data •
Temporary Parallel Implementation •
Demilitarized Zone for Components
|