Clean Code
Clean Code
Clean Code
@mariosangiorgio
Why?
Goals
int elapsedTimeInDays;
What about this?
Functions
Do one thing
public
bool
isEdible()
{
if
(this.ExpirationDate
>
Date.Now
&&
this.ApprovedForConsumption
==
true
&&
this.InspectorId
!=
null)
{
return
true;
}
else
{
return
false;
}
}
public
void
doTheDomesticThings()
{
takeOutTheTrash(); public
void
doTheDomesticThings()
{
walkTheDog();
takeOutTheTrash();
for
(Dish
dish
:
dirtyDishStack)
{
walkTheDog();
sink.washDish(dish);
doTheDishes();
teaTowel.dryDish(dish); }
}
}
public
void
turnOn(){
isOn
=
true;
} AVOID SIDE EFFECTS!
public
boolean
isOn(){
return
isOn;
}
}
Use exceptions
public
int
foo(){
...
}
public
void
bar(){
if(foo()
==
OK)
...
else
//
error
handling
}
Use exceptions
public
int
foo(){
Errors have to be encoded
...
}
public
void
bar(){
if(foo()
==
OK)
...
else
//
error
handling
}
Use exceptions
public
int
foo(){
Errors have to be encoded
...
}
public
void
bar(){
Checks (when performed)
if(foo()
==
OK) require a lot of code
...
else
//
error
handling
}
Use exceptions
public
int
foo(){
Errors have to be encoded
...
}
public
void
bar(){
Checks (when performed)
if(foo()
==
OK) require a lot of code
...
else
//
error
handling
} It’s harder to extend such
programs
Use exceptions
public
void
foo()
throws
FooException{
...
}
public
void
bar(){
try{
foo();
...
}
catch(FooException){
//
error
handling
}
}
Use exceptions
public
void
foo()
throws
FooException{ No need to mix return
...
}
values and control values
public
void
bar(){
try{
foo();
...
}
catch(FooException){
//
error
handling
}
}
Use exceptions
public
void
foo()
throws
FooException{ No need to mix return
...
}
values and control values
public
void
bar(){
try{ Cleaner syntax
foo();
...
}
catch(FooException){
//
error
handling
}
}
Use exceptions
public
void
foo()
throws
FooException{ No need to mix return
...
}
values and control values
public
void
bar(){
try{ Cleaner syntax
foo();
...
}
catch(FooException){
//
error
handling Easier to extend
}
}
Don’t Repeat Yourself
public
void
bar(){
String
[]
elements
=
{“A”,
“B”,
“C”};
public
void
bar(){
foo(“A”);
for(String
element
:
elements){
foo(“B”);
foo(element);
foo(“C”);
}
}
}
if (employee.isEligibleForFullBenefits())
Comments
GOOD BAD
Primitive obsession
It is a symptom of bad
and too much
design
parameters
Primitive obsession
public Class Car{
private int red, green, blue;
Refused bequest
Poor class hierarchy
Alternative classes with design
different interfaces
Switch vs polymorphism
public Money calculatePay(Employee e)
throws InvalidEmployeeType{
switch(e.type){
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new
InvalidEmployeeType(e.type);
}
}
Unused or
It isn’t something useful
redundant code
The couplers
Some classes are too tightly coupled
...
...
a.getTheNeededData()