SlideShare a Scribd company logo
Smells and Heuristics
Chapter 17 of Clean Code
Content
• Comments
• Environment
• Functions
• General
• Name
• Test
Comments
C1: Inappropriate
Information
• It is inappropriate for a comment to hold information
better held in a different kind of system such as your
source code control system, your issue tracking
system, or any other record-keeping system. Change
histories, for example, just clutter up source files with
volumes of historical and uninteresting text. In general,
meta-data such as authors, last- modified-date, SPR
number, and so on should not appear in comments.
• Comments should be reserved for technical notes
about the code and design.
C2: Obsolete Comment
• A comment that has gotten old, irrelevant, and
incorrect is obsolete.
• If you find an obsolete comment, it is best to
update it or get rid of it as quickly as possible.
Obsolete comments tend to migrate away from
the code they once described. They become
floating islands of irrelevance and misdirection in
the code.
C3: Redundant Comment
• A comment is redundant if it
describes something that
adequately describes itself.
• Doc that says nothing more
than (or even less than) the
function signature.
• Comments should say things
that the code cannot say for
itself.
Dirty
i++; // increment i
var user = new User(); // instantiate new User
/**

* @param sellRequest

* @return

* @throws
ManagedComponentException */
public SellResponse
beginSellItem(SellRequest sellRequest)
throws ManagedComponentException
!
Clean
// see more http://facebook/api/token
// closure variable
C4: Poorly Written Comment
• A comment worth writing is worth writing well. If
you are going to write a comment, take the time
to make sure it is the best comment you can
write. Be brief.
• Don’t ramble.
C5: Commented-Out Code
(zombie code)
• It makes me crazy to see stretches of code that
are commented out.
• When you see commented-out code, delete it!
Don’t worry, the source code control system still
remembers it. If anyone really needs it, he or she
can go back and check out a previous version.
Environment
E1: Build Requires More
Than One Step
• Building a project should be a
single trivial operation. You
should be able to check out
the system with one simple
command and then issue one
other simple command to
build it.
git clone git:/github.com/project
cd project
rails s
E2: Tests Require More Than
One Step
• You should be able to run all the unit tests with
just one command.
Functions
F1: Too Many Arguments
• Functions should have a small number of
arguments. No argument is best, followed by
one, two, and three.
F2: Output Arguments
• If your function must change
the state of something, have it
change the state of the object
it is called on.
Dirty
appendFooter(s);
public void appendFooter(StringBuffer report)
!
Clean
report.appendFooter();
F3: Flag Arguments
• Boolean arguments loudly
declare that the function does
more than one thing. They are
confusing and should be
eliminated.
Dirty!
render(true)
render(boolean isSuite)
!
Clean!
renderForSuite()
renderForSingleTest()
F4: Dead Function
• Methods that are never called should be
discarded.
General
G1: Multiple Languages in
One Source File
• The ideal is for a source file to contain one, and only one,
language.
D
irty
G2: Obvious Behavior Is Unimplemented
.
• Following “The Principle of Least Surprise,” any function or class
should implement the behaviors that another programmer could
reasonably expect.
D
irty
G3: Incorrect Behavior at the
Boundaries
• Look for every boundary condition and write a
test for it.
• Part of looking for boundaries is looking for
special conditions that can cause the test to fail.
G4: Overridden Safeties
• Turning off certain compiler warnings (or all
warnings!) may help you get the build to
succeed, but at the risk of endless debugging
sessions. Turn- ing off failing tests and telling
yourself you’ll get them to pass later is as bad as
pretending your credit cards are free money.
G5: Duplication
• Every time you see
duplication in the code, it
represents a missed
opportunity for abstraction.
• The most obvious form of
duplication is when you have
clumps of identical code that
look like some programmers
went wild with the mouse,
pasting the same code over
and over again. These should
be replaced with simple
methods.
• A more subtle form is the
‘switch’/‘case’ or ‘if’/‘else’
chain that appears again and
again in various modules,
always testing for the same
set of conditions. These
should be replaced with
polymorphism..
• Note: see more: Chapter 14@Ruby
Science
• Still more subtle are the modules that have
similar algorithms, but that don’t share similar
lines of code. This is still duplication and should
be addressed by using the TEMPLATE
METHOD,4
or STRATEGYpattern.
G6: Code at Wrong Level of
Abstraction
• It is important to create
abstractions that separate
higher level general concepts
from lower level detailed
concepts.
G7: Base Classes Depending
on Their Derivatives
• In general, base classes should know nothing
about their derivatives.
G8: Too Much Information
• Well-defined modules have
very small interfaces that
allow you to do a lot with a
little.
• Concentrate on keeping
interfaces very tight and very
small. Help keep coupling low
by limiting information.
G9: Dead Code
• Dead code is code that isn’t executed.
• When you find dead code, do the right thing.
Give it a decent burial. Delete it from the system.
G10: Vertical Separation
• Variables and function should
be defined close to where
they are used.
G11: Inconsistency
• Be careful with the conventions you choose, and
once chosen, be careful to continue to follow them.
• If within a particular function you use a variable
named responseto hold an HttpServletResponse,
then use the same variable name consistently in
the other functions that use HttpServletResponse
objects. If you name a method
processVerificationRequest, then use a similar
name, such as processDeletionRequest, for the
methods that process other kinds of requests.
G12: Clutter
• Variables that aren’t used, functions that are
never called, comments that add no information,
and so forth. All these things are clutter and
should be removed. Keep your source files
clean, well organised, and free of clutter.
G13: Artificial Coupling
• In general an artificial coupling is a result of
putting a variable, constant, or function in a
temporarily convenient, though inappropriate,
location.
• Take the time to figure out where functions,
constants, and variables ought to be declared.
G14: Feature Envy
• The methods of a class
should be interested in the
variables and functions of the
class they belong to, and not
the variables and functions of
other classes..
• ref: Feature Envy@Ruby Science
G15: Selector Arguments
• In general it is better to have
many functions than to pass
some code into a function to
select the behaviour.
G16: Obscured Intent
• We want code to be as
expressive as possible.
• Run-on expressions,
Hungarian notation, and
magic numbers all obscure
the author’s intent.
D
irty
G17: Misplaced
Responsibility
• Code should be placed where a reader would
naturally expect it to be.
• For example, where should the PI constant go?
Should it be in the Mathclass? Perhaps it
belongs in the Trigonometryclass? Or maybe
in the Circleclass?
G18: Inappropriate Static
• In general you should prefer nonstatic methods
to static methods.
• Math.max(double a, double b)is a good static
method.
G19: Use Explanatory
Variables
• One of the more powerful ways to make a
program readable is to break the calculations up
into intermediate values that are held in
variables with meaningful names.
G20: Function Names
Should Say What They Do
• Date newDate = date.add(5);

Would you expect this to add five days to the
date?
• If the function adds five days to the date and
changes the date, then it should be called
addDaysToor increaseByDays. If, on the other
hand, the function returns a new date that is five
days later but does not change the date instance,
it should be called daysLateror daysSince.
G21: Understand the
Algorithm
• It is not good enough that it passes all the tests.
You must know10
that the solution is correct.
Often the best way to gain this knowledge and
understanding is to refactor the function into
something that is so clean and expressive that it
is obvious how it works.
G22: Make Logical
Dependencies Physical
• If one module depends upon another, that
dependency should be physical, not just
logical. Rather it should explicitly ask that
module for all the information it depends upon.
G23: Prefer Polymorphism to
If/Else or Switch/Case
• Consider polymorphism before using a switch.
• The cases where functions are more volatile than
types are relatively rare. So every switch
statement should be suspect.
G24: Follow Standard
Conventions
• Every team should follow a coding standard
based on common industry norms. This coding
standard should specify things like where to
declare instance variables; how to name
classes, methods, and variables; where to put
braces; and so on.
G25: Replace Magic Numbers
with Named Constants
• You should hide raw number
behind well-named constants.
• Some constants are so easy
to recognise that they don’t
always need a named
constant.
G26: Be Precise
• When you make a decision in your code, make
sure you make it precisely.
• If you decide to call a function that might return
null, make sure you check for null.
• If there is the possibility of concurrent update,
make sure you implement some kind of locking
mechanism.
G27: Structure over
Convention
• Enforce design decisions with structure over
convention.
• For example, switch/cases with nicely named
enumerations are inferior to base classes with
abstract methods.
G28: Encapsulate
Conditionals
• Extract functions that explain the intent of the
conditional.
G29: Avoid Negative
Conditionals
• Negatives are just a bit harder
to understand than positives.
• So, when possible,
conditionals should be
expressed as positives.
G30: Functions Should Do
One Thing
• It is often tempting to create
functions that have multiple
sections that perform a series
of operations. Functions of
this kind do more than one
thing, and should be
converted into many smaller
functions, each of which does
one thing.
G33: Encapsulate Boundary
Conditions
G34: Functions Should Descend
Only One Level of Abstraction
• The statements within a function should all be
written at the same level of abstraction, which
should be one level below the operation
described by the name of the function.
G35: Keep Configurable
Data at High Levels
• see Clean Code on page G35: 337
G36: Avoid Transitive
Navigation
• If Acollaborates with B, and Bcollaborates with
C, we don’t want modules that use Ato know
about C. (For example, we don’t want
a.getB().getC().doSomething();.)
• This is sometimes called the Law of Demeter
(multiple dots).
• A method of an object should invoke only the
methods of the following kinds of objects:
1. itself
2. its parameters
3. any objects it creates/instantiates
4. its direct component objects.
Name
N1: Choose Descriptive
Names
• Make sure the name is
descriptive..
• Names are too important to
treat carelessly.
N2: Choose Names at the
Appropriate Level of Abstraction
• Choose names the reflect the
level of abstraction of the
class or function you are
working in.
N3: Use Standard
Nomenclature Where Possible
• Names are easier to understand if they are
based on existing convention or usage.
• The more you can use names that are
overloaded with special meanings that are
relevant to your project, the easier it will be for
readers to know what your code is talking about.
N4: Unambiguous Names
• Choose names that make the
workings of a function or
variable unambiguous.
N5: Use Long Names for
Long Scopes
• The length of a name should
be related to the length of the
scope.
• You can use very short
variable names for tiny
scopes.
• The longer the scope of the
name, the longer and more
precise the name should be.
N6: Avoid Encodings
• Names should not be
encoded with type or scope
information.
var str_user_name = “Mr A”;
var int_number_of_student = 0;
var global_result = 0;
N7: Names Should Describe
Side-Effects
Names should describe
everything that a function,
variable, or class is or does.
Test
T1: Insufficient Tests
• How many tests should be in a test suite?
• A test suite should test everything that could
possibly break.
T2: Use a Coverage Tool!
• Coverage tools reports gaps in your testing
strategy. They make it easy to find modules,
classes, and functions that are insufficiently
tested.
T3: Don’t Skip Trivial Tests
• They are easy to write and their documentary
value is higher than the cost to produce them.
T4: An Ignored Test Is a
Question about an Ambiguity
• Sometimes we are uncertain about a behavioral
detail because the requirements are unclear. We
can express our question about the
requirements as a test that is commented out, or
as a test that annotated with @Ignore. Which you
choose depends upon whether the ambiguity is
about something that would compile or not.
T5: Test Boundary
Conditions
Take special care to test boundary conditions.
T6: Exhaustively Test Near
Bugs
Bugs tend to congregate. When you find a bug in
a function, it is wise to do an exhaustive test of that
function. You’ll probably find that the bug was not
alone.
T7: Patterns of Failure Are
Revealing
• Complete test cases, ordered in a reasonable
way, expose patterns.
• Sometimes just seeing the pattern of red and
green on the test report is enough to spark the
“Aha!” that leads to the solution.
T8: Test Coverage Patterns
Can Be Revealing
• Looking at the code that is or is not executed by
the passing tests gives clues to why the failing
tests fail.
T9: Tests Should Be Fast
• Do what you must to keep your tests fast.
Conclusion
• This list of heuristics and smells could hardly be
said to be complete..
• You don’t become a software craftsman by
learning a list of heuristics. Professionalism and
craftsmanship come from values that drive
disciplines..
Recommended Resources.
• Detecting code smell
• Ruby Science
• Clean Code: Writing Code for Humans

More Related Content

PPTX
Clean Code
PDF
Git 101: Git and GitHub for Beginners
PPT
Time Boxing
KEY
Clean code and Code Smells
PPTX
Refactoring and code smells
PDF
PPTX
Software Craftsmanship - Code Smells - Dispensables
PPTX
Seminar clean code
Clean Code
Git 101: Git and GitHub for Beginners
Time Boxing
Clean code and Code Smells
Refactoring and code smells
Software Craftsmanship - Code Smells - Dispensables
Seminar clean code

What's hot (20)

PPTX
clean code book summary - uncle bob - English version
PPTX
Clean code
PPT
Refactoring Tips by Martin Fowler
PPTX
Java Unit Testing
PDF
Feature flags to speed up & de risk development
PPTX
PDF
Clean coding-practices
PPTX
Git 101 for Beginners
PDF
Don't Be Mocked by your Mocks - Best Practices using Mocks
PDF
Clean Code na Prática
PDF
Code Smells and Its type (With Example)
PDF
초보자를 위한 Git & GitHub
PPTX
Code smell overview
PPT
Git installation and configuration
PPTX
Golang (Go Programming Language)
ODP
Clean code
PDF
Event storming recipes
PPT
SOLID Design Principles
PPTX
A Practical Guide to Domain Driven Design: Presentation Slides
clean code book summary - uncle bob - English version
Clean code
Refactoring Tips by Martin Fowler
Java Unit Testing
Feature flags to speed up & de risk development
Clean coding-practices
Git 101 for Beginners
Don't Be Mocked by your Mocks - Best Practices using Mocks
Clean Code na Prática
Code Smells and Its type (With Example)
초보자를 위한 Git & GitHub
Code smell overview
Git installation and configuration
Golang (Go Programming Language)
Clean code
Event storming recipes
SOLID Design Principles
A Practical Guide to Domain Driven Design: Presentation Slides
Ad

Similar to Chapter17 of clean code (20)

PPTX
Clean code, Feb 2012
PDF
Clean Code
PDF
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
PPTX
Improving Code Quality Through Effective Review Process
PPTX
Clean Code
PPTX
30% faster coder on-boarding when you have a code cookbook
PPTX
Clean code
PDF
Good Coding Practices with JavaScript
PPTX
Clean Code - Writing code for human
PDF
Extracts from "Clean code"
PDF
Clean Code .Net Cheetsheets
PDF
Clean Code. An Agile Guide to Software Craft Kameron H.
PDF
Clean code and code smells
PPT
Clean code
PDF
Clean code-v2.2
PDF
Patterns, Code Smells, and The Pragmattic Programmer
PDF
Clean Code. An Agile Guide to Software Craft Kameron H.
PDF
WordCamp US: Clean Code
PDF
Software Development Standard Operating Procedure
PPT
Best practices in enterprise applications
Clean code, Feb 2012
Clean Code
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
Improving Code Quality Through Effective Review Process
Clean Code
30% faster coder on-boarding when you have a code cookbook
Clean code
Good Coding Practices with JavaScript
Clean Code - Writing code for human
Extracts from "Clean code"
Clean Code .Net Cheetsheets
Clean Code. An Agile Guide to Software Craft Kameron H.
Clean code and code smells
Clean code
Clean code-v2.2
Patterns, Code Smells, and The Pragmattic Programmer
Clean Code. An Agile Guide to Software Craft Kameron H.
WordCamp US: Clean Code
Software Development Standard Operating Procedure
Best practices in enterprise applications
Ad

Recently uploaded (20)

PPTX
MYSQL Presentation for SQL database connectivity
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation theory and applications.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Modernizing your data center with Dell and AMD
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Electronic commerce courselecture one. Pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Approach and Philosophy of On baking technology
MYSQL Presentation for SQL database connectivity
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation theory and applications.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Chapter 3 Spatial Domain Image Processing.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
NewMind AI Weekly Chronicles - August'25 Week I
Modernizing your data center with Dell and AMD
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
The AUB Centre for AI in Media Proposal.docx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
20250228 LYD VKU AI Blended-Learning.pptx
NewMind AI Monthly Chronicles - July 2025
Review of recent advances in non-invasive hemoglobin estimation
Dropbox Q2 2025 Financial Results & Investor Presentation
Electronic commerce courselecture one. Pdf
Network Security Unit 5.pdf for BCA BBA.
Approach and Philosophy of On baking technology

Chapter17 of clean code

  • 1. Smells and Heuristics Chapter 17 of Clean Code
  • 2. Content • Comments • Environment • Functions • General • Name • Test
  • 4. C1: Inappropriate Information • It is inappropriate for a comment to hold information better held in a different kind of system such as your source code control system, your issue tracking system, or any other record-keeping system. Change histories, for example, just clutter up source files with volumes of historical and uninteresting text. In general, meta-data such as authors, last- modified-date, SPR number, and so on should not appear in comments. • Comments should be reserved for technical notes about the code and design.
  • 5. C2: Obsolete Comment • A comment that has gotten old, irrelevant, and incorrect is obsolete. • If you find an obsolete comment, it is best to update it or get rid of it as quickly as possible. Obsolete comments tend to migrate away from the code they once described. They become floating islands of irrelevance and misdirection in the code.
  • 6. C3: Redundant Comment • A comment is redundant if it describes something that adequately describes itself. • Doc that says nothing more than (or even less than) the function signature. • Comments should say things that the code cannot say for itself. Dirty i++; // increment i var user = new User(); // instantiate new User /**
 * @param sellRequest
 * @return
 * @throws ManagedComponentException */ public SellResponse beginSellItem(SellRequest sellRequest) throws ManagedComponentException ! Clean // see more http://facebook/api/token // closure variable
  • 7. C4: Poorly Written Comment • A comment worth writing is worth writing well. If you are going to write a comment, take the time to make sure it is the best comment you can write. Be brief. • Don’t ramble.
  • 8. C5: Commented-Out Code (zombie code) • It makes me crazy to see stretches of code that are commented out. • When you see commented-out code, delete it! Don’t worry, the source code control system still remembers it. If anyone really needs it, he or she can go back and check out a previous version.
  • 10. E1: Build Requires More Than One Step • Building a project should be a single trivial operation. You should be able to check out the system with one simple command and then issue one other simple command to build it. git clone git:/github.com/project cd project rails s
  • 11. E2: Tests Require More Than One Step • You should be able to run all the unit tests with just one command.
  • 13. F1: Too Many Arguments • Functions should have a small number of arguments. No argument is best, followed by one, two, and three.
  • 14. F2: Output Arguments • If your function must change the state of something, have it change the state of the object it is called on. Dirty appendFooter(s); public void appendFooter(StringBuffer report) ! Clean report.appendFooter();
  • 15. F3: Flag Arguments • Boolean arguments loudly declare that the function does more than one thing. They are confusing and should be eliminated. Dirty! render(true) render(boolean isSuite) ! Clean! renderForSuite() renderForSingleTest()
  • 16. F4: Dead Function • Methods that are never called should be discarded.
  • 18. G1: Multiple Languages in One Source File • The ideal is for a source file to contain one, and only one, language. D irty
  • 19. G2: Obvious Behavior Is Unimplemented . • Following “The Principle of Least Surprise,” any function or class should implement the behaviors that another programmer could reasonably expect. D irty
  • 20. G3: Incorrect Behavior at the Boundaries • Look for every boundary condition and write a test for it. • Part of looking for boundaries is looking for special conditions that can cause the test to fail.
  • 21. G4: Overridden Safeties • Turning off certain compiler warnings (or all warnings!) may help you get the build to succeed, but at the risk of endless debugging sessions. Turn- ing off failing tests and telling yourself you’ll get them to pass later is as bad as pretending your credit cards are free money.
  • 22. G5: Duplication • Every time you see duplication in the code, it represents a missed opportunity for abstraction. • The most obvious form of duplication is when you have clumps of identical code that look like some programmers went wild with the mouse, pasting the same code over and over again. These should be replaced with simple methods.
  • 23. • A more subtle form is the ‘switch’/‘case’ or ‘if’/‘else’ chain that appears again and again in various modules, always testing for the same set of conditions. These should be replaced with polymorphism.. • Note: see more: Chapter 14@Ruby Science
  • 24. • Still more subtle are the modules that have similar algorithms, but that don’t share similar lines of code. This is still duplication and should be addressed by using the TEMPLATE METHOD,4 or STRATEGYpattern.
  • 25. G6: Code at Wrong Level of Abstraction • It is important to create abstractions that separate higher level general concepts from lower level detailed concepts.
  • 26. G7: Base Classes Depending on Their Derivatives • In general, base classes should know nothing about their derivatives.
  • 27. G8: Too Much Information • Well-defined modules have very small interfaces that allow you to do a lot with a little. • Concentrate on keeping interfaces very tight and very small. Help keep coupling low by limiting information.
  • 28. G9: Dead Code • Dead code is code that isn’t executed. • When you find dead code, do the right thing. Give it a decent burial. Delete it from the system.
  • 29. G10: Vertical Separation • Variables and function should be defined close to where they are used.
  • 30. G11: Inconsistency • Be careful with the conventions you choose, and once chosen, be careful to continue to follow them. • If within a particular function you use a variable named responseto hold an HttpServletResponse, then use the same variable name consistently in the other functions that use HttpServletResponse objects. If you name a method processVerificationRequest, then use a similar name, such as processDeletionRequest, for the methods that process other kinds of requests.
  • 31. G12: Clutter • Variables that aren’t used, functions that are never called, comments that add no information, and so forth. All these things are clutter and should be removed. Keep your source files clean, well organised, and free of clutter.
  • 32. G13: Artificial Coupling • In general an artificial coupling is a result of putting a variable, constant, or function in a temporarily convenient, though inappropriate, location. • Take the time to figure out where functions, constants, and variables ought to be declared.
  • 33. G14: Feature Envy • The methods of a class should be interested in the variables and functions of the class they belong to, and not the variables and functions of other classes.. • ref: Feature Envy@Ruby Science
  • 34. G15: Selector Arguments • In general it is better to have many functions than to pass some code into a function to select the behaviour.
  • 35. G16: Obscured Intent • We want code to be as expressive as possible. • Run-on expressions, Hungarian notation, and magic numbers all obscure the author’s intent. D irty
  • 36. G17: Misplaced Responsibility • Code should be placed where a reader would naturally expect it to be. • For example, where should the PI constant go? Should it be in the Mathclass? Perhaps it belongs in the Trigonometryclass? Or maybe in the Circleclass?
  • 37. G18: Inappropriate Static • In general you should prefer nonstatic methods to static methods. • Math.max(double a, double b)is a good static method.
  • 38. G19: Use Explanatory Variables • One of the more powerful ways to make a program readable is to break the calculations up into intermediate values that are held in variables with meaningful names.
  • 39. G20: Function Names Should Say What They Do • Date newDate = date.add(5);
 Would you expect this to add five days to the date? • If the function adds five days to the date and changes the date, then it should be called addDaysToor increaseByDays. If, on the other hand, the function returns a new date that is five days later but does not change the date instance, it should be called daysLateror daysSince.
  • 40. G21: Understand the Algorithm • It is not good enough that it passes all the tests. You must know10 that the solution is correct. Often the best way to gain this knowledge and understanding is to refactor the function into something that is so clean and expressive that it is obvious how it works.
  • 41. G22: Make Logical Dependencies Physical • If one module depends upon another, that dependency should be physical, not just logical. Rather it should explicitly ask that module for all the information it depends upon.
  • 42. G23: Prefer Polymorphism to If/Else or Switch/Case • Consider polymorphism before using a switch. • The cases where functions are more volatile than types are relatively rare. So every switch statement should be suspect.
  • 43. G24: Follow Standard Conventions • Every team should follow a coding standard based on common industry norms. This coding standard should specify things like where to declare instance variables; how to name classes, methods, and variables; where to put braces; and so on.
  • 44. G25: Replace Magic Numbers with Named Constants • You should hide raw number behind well-named constants. • Some constants are so easy to recognise that they don’t always need a named constant.
  • 45. G26: Be Precise • When you make a decision in your code, make sure you make it precisely. • If you decide to call a function that might return null, make sure you check for null. • If there is the possibility of concurrent update, make sure you implement some kind of locking mechanism.
  • 46. G27: Structure over Convention • Enforce design decisions with structure over convention. • For example, switch/cases with nicely named enumerations are inferior to base classes with abstract methods.
  • 47. G28: Encapsulate Conditionals • Extract functions that explain the intent of the conditional.
  • 48. G29: Avoid Negative Conditionals • Negatives are just a bit harder to understand than positives. • So, when possible, conditionals should be expressed as positives.
  • 49. G30: Functions Should Do One Thing • It is often tempting to create functions that have multiple sections that perform a series of operations. Functions of this kind do more than one thing, and should be converted into many smaller functions, each of which does one thing.
  • 51. G34: Functions Should Descend Only One Level of Abstraction • The statements within a function should all be written at the same level of abstraction, which should be one level below the operation described by the name of the function.
  • 52. G35: Keep Configurable Data at High Levels • see Clean Code on page G35: 337
  • 53. G36: Avoid Transitive Navigation • If Acollaborates with B, and Bcollaborates with C, we don’t want modules that use Ato know about C. (For example, we don’t want a.getB().getC().doSomething();.) • This is sometimes called the Law of Demeter (multiple dots).
  • 54. • A method of an object should invoke only the methods of the following kinds of objects: 1. itself 2. its parameters 3. any objects it creates/instantiates 4. its direct component objects.
  • 55. Name
  • 56. N1: Choose Descriptive Names • Make sure the name is descriptive.. • Names are too important to treat carelessly.
  • 57. N2: Choose Names at the Appropriate Level of Abstraction • Choose names the reflect the level of abstraction of the class or function you are working in.
  • 58. N3: Use Standard Nomenclature Where Possible • Names are easier to understand if they are based on existing convention or usage. • The more you can use names that are overloaded with special meanings that are relevant to your project, the easier it will be for readers to know what your code is talking about.
  • 59. N4: Unambiguous Names • Choose names that make the workings of a function or variable unambiguous.
  • 60. N5: Use Long Names for Long Scopes • The length of a name should be related to the length of the scope. • You can use very short variable names for tiny scopes. • The longer the scope of the name, the longer and more precise the name should be.
  • 61. N6: Avoid Encodings • Names should not be encoded with type or scope information. var str_user_name = “Mr A”; var int_number_of_student = 0; var global_result = 0;
  • 62. N7: Names Should Describe Side-Effects Names should describe everything that a function, variable, or class is or does.
  • 63. Test
  • 64. T1: Insufficient Tests • How many tests should be in a test suite? • A test suite should test everything that could possibly break.
  • 65. T2: Use a Coverage Tool! • Coverage tools reports gaps in your testing strategy. They make it easy to find modules, classes, and functions that are insufficiently tested.
  • 66. T3: Don’t Skip Trivial Tests • They are easy to write and their documentary value is higher than the cost to produce them.
  • 67. T4: An Ignored Test Is a Question about an Ambiguity • Sometimes we are uncertain about a behavioral detail because the requirements are unclear. We can express our question about the requirements as a test that is commented out, or as a test that annotated with @Ignore. Which you choose depends upon whether the ambiguity is about something that would compile or not.
  • 68. T5: Test Boundary Conditions Take special care to test boundary conditions.
  • 69. T6: Exhaustively Test Near Bugs Bugs tend to congregate. When you find a bug in a function, it is wise to do an exhaustive test of that function. You’ll probably find that the bug was not alone.
  • 70. T7: Patterns of Failure Are Revealing • Complete test cases, ordered in a reasonable way, expose patterns. • Sometimes just seeing the pattern of red and green on the test report is enough to spark the “Aha!” that leads to the solution.
  • 71. T8: Test Coverage Patterns Can Be Revealing • Looking at the code that is or is not executed by the passing tests gives clues to why the failing tests fail.
  • 72. T9: Tests Should Be Fast • Do what you must to keep your tests fast.
  • 73. Conclusion • This list of heuristics and smells could hardly be said to be complete.. • You don’t become a software craftsman by learning a list of heuristics. Professionalism and craftsmanship come from values that drive disciplines..
  • 74. Recommended Resources. • Detecting code smell • Ruby Science • Clean Code: Writing Code for Humans