Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Agile Partner - Agile Mëtteg - Clean Code

“Great code doesn’t just function: it clearly and consistently communicates your intentions, allowing other programmers to understand your code, rely on it, and modify it with confidence. But great code doesn’t just happen. It is the outcome of hundreds o
by

Cédric Pontet

on 12 July 2011

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Agile Partner - Agile Mëtteg - Clean Code

SOLID
Clean Code
Agile Mëtteg – 24 Feb 2011
We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
What is code ?
Source code
Coding...
and debugging
Who are we ?
Who are you ?
What's our role ?
What do we expect ?
People network
User story
Objectives
As a software craftsman
I want to write better code
So that my fellow developers understand
its intent
And we can maintain it easily
Not only working software, but also well-crafted software
Not only responding to change, but also steadily adding value
Not only individuals and interactions, but also a community of professionals
Not only customer collaboration, but also productive partnerships
That is, in pursuit of the items on the left we have found the items on the right to be indispensable.
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:
Manifesto for
Software Craftsmanship
Manifesto for
Agile Software Development
That is, while there is value in the items on
the right, we value the items on the left more.
Why write
clean code ?

How to keep your code clean ?
Coding and
debugging
Detailed
design
Unit
testing
Integration
Integration
Testing
Corrective
maintenance
Requirement development
Planning
Problem definition
Software architecture
System testing
Software development process
Coding is part of Design, Development & Test
... for each iteration
Waterfall approach
Iterative approach
Is code really important ?
The only part of software development that cannot be skipped
But then don’t ask for maintenance or additional features…
A mechanical process? (Code = Encode)
Who cares as long as it runs!
No! The same thing can be coded in a lot of different ways.
Some ways may be better than others
Clean Code & Metaphors
Craftsmanship : idea of quality in the work

A better code A better programmer
We are professional!
Cleaning code ?!

Cleaning is an iterative process (Boy scout camp rule)
Code smells
Letter-writing

« Plan to throw one away, you will anyhow »
Fred Brooks - The Mythical Man-Month – 1975-1995

... Unacceptable !
Software development 1st metaphor
Construction metaphor

Intellectual toolbox
Do not reinvent the wheel!
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 {

}

}
Wanna get scared ?
Who is scared now ?
This is "one" method, where only the code blocks have been kept
218 lines of
if-then-else and
try-catch-finally
What about this one ?
Inline javascript in the onclick event handler
Long method
Poor readability
Useless comments
Comments to explain what is being done
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.
Clean Code, Robert C. Martin
Let's talk about bugs
Defects can be introduced during
Requirements
Architecture
Design & coding

Clean code
Less bug introduced during design & coding
All kind of bugs cost less to fix
Cost of bugs
The later a bug is detected and fixed, the more it costs
What is bad code ?
Unreadable
Not easy to understand
Classes are tightly coupled
Not easy to change
Does not communicate the intent
Shows too much of the internals
Code smells
Duplicated code
Long methods
Too many arguments
Switch statements
Large class
Comments
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
Readability
Understandability
Testability
Flexibility
Modularity
Evolutivity
Reusability
Maintainability
Improving the -ities
Buzz
SRP
KISS
YAGNI
DRY
DIE
Law of
Demeter
Loose coupling
POLS
Single Responsibility Principle
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.
Keep it simple, Stupid!
Keep it short and simple
Keep it simple AND stupid
Keep it simple and straightforward
Simplicity should be a key goal in design, and that unnecessary complexity should be avoided.
You ain't gonna need it
Programmers should not add functionality until it is necessary
Always implement things when you actually need them, never when you just foresee that you need them
Don't repeat yourself
Duplication is evil
Reducing repetition of information of all kinds
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Principle of Least Knowledge
Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
A loosely coupled system is one where each of its components has little or no knowledge of the definitions of other separate components
Coupling refers to the degree of direct knowledge that one class has of another
Principle of Least Surprise
When two elements conflict, or are ambiguous, the behaviour should be that which will least surprise the user
Meaningful names
Functions
/*Comments*/
Formatting
Objects and
data structures
Classes
Error
handling
Avoid encodings
Intention revealing names
Avoid disinformation
Make meaningful distinctions
Use pronouncable names
Avoid mental mappings
Use searchable names
Hungarian notation
Do not use it
Modern IDE give you type information
Makes it harder to change the name or type of a variable, function, or class.
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
classes
methods
parameters
variables
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.
Uncle Bob says
Even if you are coding a hypotenuse and "hp" looks like a good abbreviation, it could be disinformative
Do not refer to a grouping of accounts as an "accountList" unless it’s actually a "List"
Beware of using names which vary in small ways
Spelling similar concepts similarly is information
"L" lower-case or "one"
"O" upper-case or "zero"
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
Avoid things such as
p1, p2, p3 for parameters
naming a variable "klass" because keyword "class" is reserved
creating "ProductInfo" or "ProductData" when you already have a class "Product"
naming a variable "theZork" because you already have another named "zork"
using "variable" in the name of a variable, "table" in the name of a table, "Object" in the name of an object
Noise words are redundant.
If you can’t pronounce it, you can’t discuss it without sounding like an idiot.
Single-letter names and numeric constants have a particular problem in that they are not easy to locate across a body of text.
Single-letter names can ONLY be used as local variables inside short methods.
The length of a name should correspond to the size of its scope
If a variable or constant might be seen or used in multiple places in a body of code, it is imperative to give it a search-friendly name
Encoding type or scope information into names simply adds an extra burden of deciphering
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
One difference between a smart programmer and a professional programmer is that the professional understands that "clarity is king"
Readers shouldn’t have to mentally translate your names into other names they already know.
Source : Clean Code by Robert C. Martin
Class names
Classes and objects should have noun or noun phrase names
A class name should not be a verb
Avoid words like "Manager", "Processor", "Data", or "Info"
Method Names
Methods should have verb or verb phrase names
When constructors are overloaded, use static factory methods with names that describe the arguments
Pick One Word
per Concept
fetch
retrieve
get
controller
manager
driver
A consistent lexicon is a great boon to the programmers who must use your code
Avoid using the same word for two different purpose
Use Solution Domain Names
Ubiquitous
Language
Use Problem Domain Names
Don’t Add Gratuitous Context
Use
computer science terms
algorithm names
pattern names
math terms
... and so forth
The programmer who maintains your code can ask a domain expert what it means
The code that has more to do with problem domain concepts should have names drawn from the problem domain
Separating solution and problem domain concepts is part of the job of a good programmer and designer
Avoid things such as
Reusing the class name in a field name : Contact.ContactName
Prefixing all classe names by the application name : T2Request
Namespaces are used for that purpose
Prefixing the name may be necessary as a last resort
Domain Driven Design by Eric Evans
Small
The first rule of functions is that they should be small.
The second rule of functions is that they should be smaller than that.
Some say
7 lines, no more
Do One Thing
Functions should do one thing
They should do it well
They should do it only
The reason we write functions is to decompose a larger concept into a set of steps at the next level of abstraction
One Level of Abstraction
per Function
Switch statement
Use descriptive
names
Function arguments
Have no side effects
Command query separation
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.
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
Reading Code from Top to Bottom : The Stepdown Rule
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
It’s hard to make a small switch statement
It’s also hard to make a switch statement that does one thing
"You know you are working on clean code when each routine turns out to be pretty much what you expected."
Ward Cunnigham
Don’t be afraid to make a name long.
A long descriptive name is better than a short enigmatic name.
A long descriptive name is better than a long descriptive comment.
Use a naming convention that allows multiple words to be easily read in the function names
The ideal number of arguments for a function is zero
When more than two or tree arguments, consider using parameter objects
Flag arguments are ugly
They loudly proclaim that the function does more than one thing
Number of parameters
render(true)
renderForSuite() and renderForSingleTest()
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
A function promises to do one thing, but it also does other hidden things
A side effect creates a temporal coupling
Temporal couplings are confusing, especially when hidden as a side effect
If you must have a temporal coupling, you should make it clear in the name of the function (i.e. checkPasswordAndInitializeSession)
Functions should either
do something
or answer something
but not both
Either your function should change the state of an object, or it should return some information about that object
Comments do not make up for bad code
Explain yourself in code
Bad
Principles
The Total Cost of Owning a Mess
Done poorly, commenting is a waste of time, and often harmful
Good code is its own best documentation
Try first to improve the code so it doesn't need comments
Comments should say things about the code that the code can't say about itself
Comments are often out of date
Good
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Martin Fowler
Code is more often read than it is written
Vertical formatting
Code formatting is about communication
Distance
Reading code like reading a book, or a newspaper article
Openness
White lines to separate concepts (i.e. methods in a class)
Density
Lines of code that are tightly related should appear vertically dense
Closely related concepts vertically close to each other
One function calling another should be vertically close
The caller should be above the callee
Variables should be declared close to their usage
Instance variables should be declared at the top of the class
Misleading comment
Explanation of intent
Comment tricky code
Horizontal formatting
Keep our lines short
One operation per line
Openness and Density
Length
Use horizontal white space to associate things that are strongly related
Use white space wisely to improve readability
Indentation
A source file is a hierarchy rather like an outline
One convention for the team
Use your IDE to enforce it
Think about maintainability
The goal is to show the logical organization of the code
Looking good is only secondary
Commented-Out Code
Use source control
Xml docs in Public APIs
Xml docs in Nonpublic Code
Ron Jeffries
Especially useful in multi-tier architectures
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
Side effect =
Code markers
Objects hide their data behind abstractions and expose functions that operate on that data
Data structures expose their data and have no meaningful functions
Typical data structure
Data transfer object
Difference between objects and data structures
Objects expose behavior and hide data
Data structures expose data and have no significant behavior
easy to add new kinds of objects without changing existing behaviors
hard to add new behaviors to existing objects
easy to add new behaviors to existing data structures
hard to add new data structures to existing functions
Organization
Public static constants
Private static variables
Private instance variables
Variables
Functions
Public functions
Private utilities called by a public function right after the public function itself
Encapsulation
Class interface hides implementation details
Keep variables and utility functions private
Loosening encapsulation is always a last resort
Small
As with functions, smaller is the primary rule when it comes to designing classes
Consistent abstraction
One responsibility
One reason to change
Single Responsibility Principle
The interface of the class exposes the members with same level of abstraction
Cohesion
Many small classes
The more variables a method manipulates the more cohesive that method is to its class
High cohesion means that variables and methods are co-dependant
Split one class into two to make them more cohesive
Breaking a large function into many smaller functions often gives us the opportunity to split several smaller classes out as well
Reduce coupling
Use interfaces to decouple classes from each other
Avoid bidirectional dependencies
Avoid semantic or time dependant coupling
Avoid deep inheritance hierarchies
Organizing for change
Use exception rather than return code
Don’t swallow exceptions
Use finally block to clean up
Provide context when throwing exception
Fail fast
Handle exceptions as soon as possible
Exceptions should stay exceptionnal
Performance cost
Don't forget alternatives
defensive programming
design by contracts : pre-conditions, post-conditions, invariants
How to achieve this ?
Successive refinement
Refactoring
First make it work, then make it right
TDD mantra
Red, Green, Refactor
Do not reinvent the wheel
Use what is already out there
IDEs
Libraries
Frameworks
Tools
Code metrics
Conclusion
Think about the "What", then the "How"
Redundant comments / Noise
Remove noise
Maintaining clean code = Managing code complexity
Refactor ruthlessly
Tests are code and should be cleaned up like production code
Your tests harness is your safety net
Direct benefit : design emergence
Don’t be limited by your language
Become a software craftsman
"Don't document bad code - rewrite it"
Kernighan & Pauger
This presentation is mainly based on these two books
We also recommend these
Use TODO
Easy to neglect...
But represents 50-65% of the overall effort
And source of 50-75% of the bugs
Have you seen the deadline!?
What was hard to write should be hard to read!
Not a professional attitude
Code will be more read than written...
Good code and good programmers help productivity
Customer
AssetFactory
OrderRepository
JobState
AuthorizationContext
AuthenticateUser
SendPayment
AddNewOrderLine
OpenSession
Save
Typical example of working against your IDE
Lieberherr & Holland - 1989
_account.getContactPerson()
_account.getContactPerson().getSchedule()
_account.getContactPerson().getSchedule().getVacations().add...
Beware of Train wrecks!
Use your IDE refactoring features
Extract method
Rename
Extract interface
Promote variable
Encapsulate field
Reorder parameters
Self documenting code
Eric Ferrot
eferrot@agilepartner.net

Cédric Pontet
cpontet@agilepartner.net

They will save you time and tedious effort
a professional whose work is consistently of high quality : "as an actor he was a consummate craftsman"
a creator of great skill in the manual arts : "the jewelry was made by internationally famous craftsmen"
What is a craftsman ?
In 2009 the idea of software craftsmanship was generalized
by people like Robert C. Martin and Correy Haines
There should never be more than one reason for a class to change
Separation of concerns
Kelly Johnson
Ron Jeffries
Andy Hunt and Dave Thomas
Karl Weick
Product.GetById(id)
Product.GetByReference(reference)
cqrs
Bertrand Meyer
OCP
Open/Close Principle
Open for extension
Closed to modification
Abstraction is the Key
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.
Polymorphism
LSP
Liskov Substitution Principle
Objects should be replaceable with instances of their subtypes without altering correctness
Square is not Rectangle
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.
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.
ISP
Interface Segregation Principle
Many client-specific interfaces are better than one general-purpose interface
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.
DIP
Depend on abstractions, not on concretions
Dependency Inversion Principle
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
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.
Robert C. Martin aka Uncle Bob
A crap odyssey
did you mean cars
Notice anything wrong here ?
Full transcript