Create your own polished presentation in minutes. Just describe what you need.
Free to try, no credit card requiredObjectives
Is code really important ?
The only part of software development that cannot be skipped
Letter-writing
« Plan to throw one away, you will anyhow »
Fred Brooks - The Mythical Man-Month – 1975-1995
... Unacceptable !
Construction metaphor
Craftsmanship : idea of quality in the work
Cleaning code ?!
Why write
clean code ?
How to keep your code clean ?
Beware of Train wrecks!
How to achieve this ?
Use your IDE refactoring features
People network
Who are you ?
Who are we ?
What's our role ?
User story
As a software craftsman
I want to write better code
So that my fellow developers understand
its intent
And we can maintain it easily
What do we expect ?
As the mess builds, the productivity of the team continues to decrease, asymptotically approaching zero. As productivity decreases, management does the only thing they can; they add more staff to the project in hopes of increasing productivity. […] they, and everyone else on the team, are under horrific pressure to increase productivity. So they all make more and more messes, driving the productivity ever further toward zero.
Wanna get scared ?
Corrective
maintenance
This is "one" method, where only the code blocks have been kept
Clean Code, Robert C. Martin
Integration
Integration
Testing
Problem definition
Detailed
design
System testing
Coding and
debugging
Notice anything wrong here ?
The Total Cost of Owning a Mess
A crap odyssey
What about this one ?
Requirement development
Planning
Unit
testing
Software architecture
Software development process
What is code ?
and debugging
Improving the -ities
Clean Code
Easy to neglect...
A mechanical process? (Code = Encode)
Who cares as long as it runs!
Have you seen the deadline!?
What was hard to write should be hard to read!
Let's talk about bugs
Buzz
Defects can be introduced during
Clean code
Cost of bugs
The later a bug is detected and fixed, the more it costs
Software development 1st metaphor
Code is the center of our work
Our code base is the working software
It is often the only faithfull description/documentation of the software
Modeling and designing means nothing without implementing code
A beautiful model on paper is no use to the end user
The quality of the code impacts the overall quality of the software
Agile Mëtteg – 24 Feb 2011
Waterfall approach
Coding is part of Design, Development & Test
Clean Code & Metaphors
What is bad code ?
... for each iteration
Code smells
Iterative approach
Eric Ferrot
eferrot@agilepartner.net
public boolean foo() {
try {
synchronized () {
if () {
} else {
}
for () {
if () {
if () {
if () {
if ()
{
if () {
for () {
}
}
}
} else {
if () {
for () {
if () {
} else {
}
if () {
} else {
if () {
}
}
if () {
if () {
if () {
for () {
}
}
}
} else {
}
}
} else {
}
}
}
}
}
if () {
}
if () {
for () {
if () {
if () {
if () {
if () {
if () {
for () {
}
}
} else {
if () {
for () {
if () {
} else {
if () {
}
}
}
if () {
if () {
if () {
for () {
}
}
}
} else {
}
}
}
} else {
if () {
for () {
if () {
} else {
if () {
}
}
}
if () {
if () {
if () {
if () {
for () {
}
}
} else {
if () {
if () {
for () {
}
}
} else {
if () {
for () {
}
}
}
}
}
} else {
}
} else {
}
}
}
}
}
}
if () {
for () {
for () {
if () {
} else {
if ()
else
}
}
if () {
try {
} catch () {
}
}
}
} else {
}
if () {
} else {
try {
if () {
for () {
if ()
else
}
}
if () {
for () {
}
}
if () {
for () {
}
}
if () {
for () {
}
}
if () {
for () {
}
}
} catch () {
}
if () {
for () {
try {
if ()
else
} catch () {
try {
} catch () {
}
}
}
}
}
try {
} catch () {
}
if () {
if () {
for () {
if () {
for () {
if () {
} else {
if ()
else
}
}
if () {
try {
} catch () {
}
}
}
}
}
}
if ()
try {
} catch () {
}
if () {
if () {
for () {
if () {
try {
} catch () {
}
}
}
}
}
if ()
return ();
}
} finally {
}
}
Manifesto for
Software Craftsmanship
In 2009 the idea of software craftsmanship was generalized
by people like Robert C. Martin and Correy Haines
Manifesto for
Agile Software Development
What is a craftsman ?
As aspiring Software Craftsmen we are raising the bar of professional software development by practicing it and helping others learn the craft. Through this work we have come to value:
We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:
That is, while there is value in the items on
the right, we value the items on the left more.
That is, in pursuit of the items on the left we have found the items on the right to be indispensable.
218 lines of
if-then-else and
try-catch-finally
Who is scared now ?
Choosing good names for a function can go a long way toward explaining the intent of the function and the order and intent of the arguments
Function arguments
Side effect =
A function promises to do one thing, but it also does other hidden things
Switch statement
Number of parameters
Have no side effects
"You know you are working on clean code when each routine turns out to be pretty much what you expected."
Ward Cunnigham
They can be tolerated if they appear only once, are used to create polymorphic objects, and are hidden behind an inheritance relationship so that the rest of the system can’t see them
Flag arguments are ugly
They loudly proclaim that the function does more than one thing
render(true)
renderForSuite() and renderForSingleTest()
Use descriptive
names
The name of a variable, function, or class, should answer all the big questions. It
should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.
Intention revealing names
It is not sufficient to add number series or noise words, even though the compiler is satisfied. If names must be different, then they should also mean something different
Functions
Make meaningful distinctions
Choosing good names takes time but saves more than it takes. So take care with your names and change them when you find better ones.
For
Avoid disinformation
Avoid things such as
Reading Code from Top to Bottom : The Stepdown Rule
Functions should either
Noise words are redundant.
We want every function to be followed by those at the next level of abstraction so that we can read the program, descending one level of abstraction at a time as we read down the list of functions
Command query separation
Ubiquitous
Language
Prefixing the name may be necessary as a last resort
Bertrand Meyer
One Level of Abstraction
per Function
Method Names
Don’t Add Gratuitous Context
cqrs
Class names
did you mean cars
The reason we write functions is to decompose a larger concept into a set of steps at the next level of abstraction
Either your function should change the state of an object, or it should return some information about that object
Avoid things such as
Typical example of working against your IDE
Domain Driven Design by Eric Evans
Product.GetById(id)
Product.GetByReference(reference)
Mixing levels of abstraction within a function is always confusing. Readers may not be able to tell whether a particular expression is an essential concept or a detail. Worse, like broken windows, once details are mixed with essential concepts, more and more details tend to accrete within the function.
Do One Thing
Some say
7 lines, no more
Small
The first rule of functions is that they should be small.
Pick One Word
per Concept
The second rule of functions is that they should be smaller than that.
Meaningful names
Use Solution Domain Names
Use Problem Domain Names
Use
Separating solution and problem domain concepts is part of the job of a good programmer and designer
Readers shouldn’t have to mentally translate your names into other names they already know.
Comments do not make up for bad code
Avoid mental mappings
Explain yourself in code
Single-letter names and numeric constants have a particular problem in that they are not easy to locate across a body of text.
One difference between a smart programmer and a professional programmer is that the professional understands that "clarity is king"
Use searchable names
Encoding type or scope information into names simply adds an extra burden of deciphering
Use pronouncable names
bBusy : boolean
chInitial : char
cApples : count of items
dwLightYears : double word (systems)
fBusy : boolean (flag)
nSize : integer (systems) or count (application)
iSize : integer (systems) or index (application)
fpPrice: floating-point
dbPi : double (systems)
pFoo : pointer
rgStudents : array, or range
szLastName : zero-terminated string
u32Identifier : unsigned 32-bit integer (systems)
stTime : clock time structure
fnFunction : function name
Avoid encodings
If you can’t pronounce it, you can’t discuss it without sounding like an idiot.
Hungarian notation
/*Comments*/
Reading code like reading a book, or a newspaper article
One convention for the team
Horizontal formatting
Vertical formatting
Uncle Bob says
Length
Openness
Density
Openness and Density
Distance
Indentation
Remove noise
Redundant comments / Noise
Use source control
Commented-Out Code
Code is more often read than it is written
Source : Clean Code by Robert C. Martin
Formatting
Explanation of intent
Misleading comment
Use TODO
"Don't document bad code - rewrite it"
Code markers
Comment tricky code
Kernighan & Pauger
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Self documenting code
Martin Fowler
Xml docs in Nonpublic Code
Xml docs in Public APIs
Code formatting is about communication
Difference between objects and data structures
Classes
Organization
Encapsulation
Variables
Functions
Reduce coupling
As with functions, smaller is the primary rule when it comes to designing classes
Small
Consistent abstraction
One responsibility
Objects and
data structures
Error
handling
Many small classes
Cohesion
Objects expose behavior and hide data
Data structures expose data and have no significant behavior
Exceptions should stay exceptionnal
Typical data structure
Data transfer object
Performance cost
Don't forget alternatives
Many client-specific interfaces are better than one general-purpose interface
ISP
Clients should not be forced to depend upon interfaces they do not use
Otherwise, clients are subject to changes in those interfaces. This results in an inadvertent coupling between all the clients.
When a client depends upon a class that contains interfaces that the client does not use, but that other clients do use, then that client will be affected by the changes that those other clients force upon the class.
Interface Segregation Principle
There should never be more than one reason for a class to change
Depend on abstractions, not on concretions
SRP
A. High level modules should not depend upon low level module. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions
DIP
Single Responsibility Principle
Separation of concerns
Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.
Dependency Inversion Principle
The goal of the dependency inversion principle is to decouple application glue code from application logic. Reusing low-level components (application logic) becomes easier and maintainability is increased.
This is facilitated by the separation of high-level components and low-level components into separate packages/libraries, where interfaces defining the behavior/services required by the high-level component are owned by, and exist within the high-level component's package.
SOLID
Open for extension
Closed to modification
OCP
Abstraction is the Key
Square is not Rectangle
Objects should be replaceable with instances of their subtypes without altering correctness
The behavior of a Square object is not consistent with the behavior of a Rectangle object.
Behaviorally, a Square is not a Rectangle.
And it is behavior that software is really all about.
Open/Close Principle
By creating base classes with override-able functions, we are able to create new classes that do the same thing differently without changing the base functionality.
Further, if properties of the abstracted class need to be compared or organized together, another abstraction should handle this.
LSP
Polymorphism
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
In other words, if you are calling a method defined at a base class upon an abstracted class, the function must be implemented properly on the subtype class.
Liskov Substitution Principle
Robert C. Martin aka Uncle Bob
Keep it simple AND stupid
Keep it simple, Stupid!
Simplicity should be a key goal in design, and that unnecessary complexity should be avoided.
DRY
KISS
Reducing repetition of information of all kinds
Keep it simple and straightforward
Don't repeat yourself
Keep it short and simple
Kelly Johnson
Especially useful in multi-tier architectures
Andy Hunt and Dave Thomas
Programmers should not add functionality until it is necessary
Duplication is evil
You ain't gonna need it
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
DIE
YAGNI
Ron Jeffries
Always implement things when you actually need them, never when you just foresee that you need them
Ron Jeffries
Principles
Principle of Least Surprise
Principle of Least Knowledge
POLS
When two elements conflict, or are ambiguous, the behaviour should be that which will least surprise the user
In particular a programmer should try to think of the behavior that will least surprise someone who uses the program, rather than that behavior that is natural from knowing the inner workings of the program
Law of
Demeter
Coupling refers to the degree of direct knowledge that one class has of another
Loose coupling
Lieberherr & Holland - 1989
Karl Weick
A loosely coupled system is one where each of its components has little or no knowledge of the definitions of other separate components
Do not reinvent the wheel
Successive refinement
Use what is already out there
They will save you time and tedious effort
Refactoring
TDD mantra
Red, Green, Refactor
First make it work, then make it right
Cédric Pontet
cpontet@agilepartner.net
Conclusion
This presentation is mainly based on these two books
Refactor ruthlessly
Maintaining clean code = Managing code complexity
Think about the "What", then the "How"
Your tests harness is your safety net
Don’t be limited by your language
Direct benefit : design emergence
Tests are code and should be cleaned up like production code
We also recommend these
Become a software craftsman
Inline javascript in the onclick event handler
Good
Bad
Long method
Useless comments
Comments to explain what is being done
Poor readability
Create your own polished presentation in minutes. Just describe what you need.
Free to try, no credit card required