SlideShare a Scribd company logo
1 of 74
Download to read offline
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

What's hot

Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Name
nahid035
 
Coding Standards & Best Practices for iOS/C#
Coding Standards & Best Practices for iOS/C#Coding Standards & Best Practices for iOS/C#
Coding Standards & Best Practices for iOS/C#
Asim Rais Siddiqui
 
Clean Code III - Software Craftsmanship
Clean Code III - Software CraftsmanshipClean Code III - Software Craftsmanship
Clean Code III - Software Craftsmanship
Theo Jungeblut
 

What's hot (20)

Clean code
Clean codeClean code
Clean code
 
Clean code
Clean code Clean code
Clean code
 
Clean Code summary
Clean Code summaryClean Code summary
Clean Code summary
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Clean Code
Clean CodeClean Code
Clean Code
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 
Clean code: meaningful Name
Clean code: meaningful NameClean code: meaningful Name
Clean code: meaningful Name
 
Clean code
Clean codeClean code
Clean code
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Clean code
Clean codeClean code
Clean code
 
Coding Standards & Best Practices for iOS/C#
Coding Standards & Best Practices for iOS/C#Coding Standards & Best Practices for iOS/C#
Coding Standards & Best Practices for iOS/C#
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
Coding Best Practices
Coding Best PracticesCoding Best Practices
Coding Best Practices
 
Code smell overview
Code smell overviewCode smell overview
Code smell overview
 
Clean Code III - Software Craftsmanship
Clean Code III - Software CraftsmanshipClean Code III - Software Craftsmanship
Clean Code III - Software Craftsmanship
 
Clean Code
Clean CodeClean Code
Clean Code
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility Principle
 
Code Smells and Its type (With Example)
Code Smells and Its type (With Example)Code Smells and Its type (With Example)
Code Smells and Its type (With Example)
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
 

Similar to Chapter17 of clean code

C STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptxC STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptx
SKUP ACADEMY
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
cobyst
 
The View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tipsThe View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tips
Bill Buchan
 

Similar to Chapter17 of clean code (20)

Principled And Clean Coding
Principled And Clean CodingPrincipled And Clean Coding
Principled And Clean Coding
 
C STANDARDS (C17).pptx
C STANDARDS (C17).pptxC STANDARDS (C17).pptx
C STANDARDS (C17).pptx
 
C STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptxC STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptx
 
C STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptxC STANDARDS (C17) (1).pptx
C STANDARDS (C17) (1).pptx
 
C STANDARDS (C17).pptx
C STANDARDS (C17).pptxC STANDARDS (C17).pptx
C STANDARDS (C17).pptx
 
Software Craftmanship - Cours Polytech
Software Craftmanship - Cours PolytechSoftware Craftmanship - Cours Polytech
Software Craftmanship - Cours Polytech
 
Clean code
Clean codeClean code
Clean code
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
 
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
 
YAGNI Principle and Clean Code
YAGNI Principle and Clean CodeYAGNI Principle and Clean Code
YAGNI Principle and Clean Code
 
Coding Standards
Coding StandardsCoding Standards
Coding Standards
 
代码大全(内训)
代码大全(内训)代码大全(内训)
代码大全(内训)
 
Clean Code - Part 2
Clean Code - Part 2Clean Code - Part 2
Clean Code - Part 2
 
Clean Code V2
Clean Code V2Clean Code V2
Clean Code V2
 
Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)
 
Reading Notes : the practice of programming
Reading Notes : the practice of programmingReading Notes : the practice of programming
Reading Notes : the practice of programming
 
Code Smells and Refactoring - Satyajit Dey & Ashif Iqbal
Code Smells and Refactoring - Satyajit Dey & Ashif IqbalCode Smells and Refactoring - Satyajit Dey & Ashif Iqbal
Code Smells and Refactoring - Satyajit Dey & Ashif Iqbal
 
Clean code presentation
Clean code presentationClean code presentation
Clean code presentation
 
The View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tipsThe View - 30 proven Lotuscript tips
The View - 30 proven Lotuscript tips
 
Improving Code Quality Through Effective Review Process
Improving Code Quality Through Effective  Review ProcessImproving Code Quality Through Effective  Review Process
Improving Code Quality Through Effective Review Process
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 

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