SlideShare a Scribd company logo
Clean Code and
Code Smells
Md Aftab Uddin Kajal
Software Engineer
SELISE rockin' software
WANT TO BE BETTER
“You are reading this book for two reasons. First, you
are a programmer. Second, you want to be a better
programmer. We need better programmers.”
-- ROBERT C. MARTIN
The Boy Scout Rule
Robert C. Martin
Uncle Bob
Elegance
I like my code to be elegant and efficient. The
logic should be straightforward to make it hard
for bugs to hide, the dependencies minimal to
ease maintenance, error handling complete
according to an articulated strategy, and
performance close to optimal so as not to
tempt people to make the code messy with
unprincipled optimizations. Clean code does
one thing well.
-- Bjarne Stroustrup
Simple, direct, prose
Clean code is simple and direct. Clean code reads like
well-written prose. Clean code never obscures the designer’s
intent but rather is full of crisp abstractions and straightforward
lines of control.
Grady Booch
Literate
Clean code can be read, and enhanced by a
developer other than its original author. It has unit
and acceptance tests. It has meaningful names. It
provides one way rather than many ways for doing
one thing. It has minimal dependencies, which are
explicitly defined, and provides a clear and minimal
API. Code should be literate since depending on the
language, not all necessary information can be
expressed clearly in code alone.
-- Dave Thomas
Care
Clean code always looks like it was
written by someone who cares
Michael Feathers
Small, expressive, simple
Reduced duplication, high
expressiveness, and early building of,
simple abstractions
Ron Jeffries
What you expected
You know you are working on clean
code when each routine you reads turns
out to be pretty much what you
expected
-- Ward Cunningham
Clean code and code smells
Clean and Bad Code
Bad Code:
- We all have seen bad code/code smells.
- We have all written bad code.
- How can we written bad code?
- If it doesn't work - that's bad.
- But what if it works? - compiles, run and produces the expected output.
Clean and Bad Code
Bad Code:
- Most of the times for the clients output is good enough.
- But as professionals we know that's not enough.
- We don't do justice to us or our clients if we are just satisfied with a code
that's just working.
- Scenario: We had a deadline, we needed to get the job done so we have written some bad
code. The client is happy with the end result, and doesn't get by the bad code. After few days,
client wants us to do a small change, and since it's small he gives us a very short deadline. We
are confident we can do it, So start coding. it turns out that, because of our bad coding, we now
need to make changes a lot of places to add the new change. This is giving us a headache. And
the client now doesn't understand why it is taking us so long to make a small change, he is no
longer happy.
Clean and Bad Code
Clean Code:
- It's not enough to write code well.
- The code has to be kept clean over time.
- We have all seen code rot and degrade as time passes.
- Leave the campground cleaner than you found it.
The Boy Scout Rule
Meaningful names
A simple example
What does it mean?
Days? Diameter? ...int d;
Is this any better?int d;
//elapsed time
in days
What about this?
int elapsedTimeInDays;
A simple example
public List<int[]> GetThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x in theList){
if (x[0] == 4)
list1.add(x);
}
return list1;
}
This code is quite simple but what does it do?
Looking at it we can’t tell what it is actually doing!
A simple example
public List<int[]> GetFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell in gameBoard){
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(x);
}
return flaggedCells;
}
Is this code any better?
A simple example
public List<Cell> GetFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell in gameBoard){
if (cell.isFlagged())
flaggedCells.add(x);
}
return flaggedCells;
}
What about this?
A simple example
What we have done:
flaggedCells
rather than list1
used intention revealing names
cell[STATUS_VALUE] rather than x[0]replaced magic numbers with
constants
Cell cell rather than int[] cellcreated an appropriate abstract
data type
Meaningful Names
int a = l;
if (O == l){
a = O1;
}else{
l = 01;
}
Avoid Disinformation
public static void CopyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i];
}
}
Make Meaningful Distinctions
Meaningful Names
class DtaRcrd102
{
private DateTime genymdhms;
private DateTime modymdhms;
private string pszqint = "102";
/* ... */
}
Use Pronounceable Names
class Customer
{
private DateTime generationTimestamp;
private DateTime modificationTimestamp;
private String recordId = "102";
/* ... */
}
Meaningful Names
for (int j = 0; j< 34; j++) {
s += (t[j] * 4) / 5;
}
Use Searchable Names
Meaningful Names
int realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j = 0; j<NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
Use Searchable
Names
Meaningful Names
Member Prefixes (Avoid encodings)
public class Part{
public string m_dsc{get; set;}
}
public class Part{
public string Description{get; set;}
}
Meaningful Names
Hungarian Notation (Avoid encodings)
PhoneNumber phoneString;
// name not changed when type changed!
PhoneNumber phone;
Meaningful Names
for (a = 0; a < 10; a++)
for (b = 0; b < 10; b++)
Avoid Mental Mapping
Meaningful Names
Manager, Processor, Data, Info
Class Names
Customer, WikiPage, Account, AddressParser
// a class name should not be a verb
Classes and objects should have noun
or noun phrase names
Meaningful Names
Method Names
Methods should have verb or verb phrase names like PostPayment, DeletePage, or Save
Meaningful Names
Pick One Word per Concept
Fetch, Retrieve, Get // as equivalent methods
Controller, Manager, Driver // confusing
Meaningful Names
Use Solution Domain Names
AccountVisitor, JobQueue
// people who read your code will be programmers
Add Meaningful Context
firstName, lastName, street, city, state, zipcode
// a better solution
addrFirstName, addrLastName, addrState
// a better solution
Class Address
Meaningful Names
Don’t Add Gratuitous Context
Address
// is a fine name for a class
AccountAddress, CustomerAddress
// are fine names for instances of the class Address
// but could be poor names for classes
MAC addresses, port addresses, Web addresses
// a better solution
PostalAddress, MAC, URI
Functions
Characteristics ~ Size:
- Should be small. How small ?
- Each should be Two/Three/Four lines, by not sacrificing readability.
- Each should be transparently obvious.
- Each should be tell a story.
- They Should be not be large enough to hold too many nested structures.
- The indent level of a function should not be greater than one or two.
Functions
Characteristics ~ One Thing:
- Should only do one thing.
- Should do that thing well.
- How to find whether a function is doing more than one thing?
- If we can extract another function from it with a name that is not merely a restatement of its implementation.
- Functions that do only one thing, cannot be divided into sections.
Functions
Characteristics ~ Abstraction:
- One level of abstraction.
- Mixing levels of abstraction within a function will be confusing for the reader.
- Every function should be followed by those at the next level of abstraction.
Step Down Rule.
- Function should change the state of an object, or it should return some information about that object. Doing both
often leads to confusion.
Functions
Characteristics ~ Names:
- User descriptive name
- Don't be afraid to make a name long.
- Don’t be afraid to spend time choosing a name.
- Try several different names and read the code to see whether the name fits or not.
Functions
Characteristics ~ Arguments:
- Ideal number of arguments for a function is zero.
- Next comes one.
- Followed by two.
- Three arguments should be avoided where possible.
- More than three requires very special justification and shouldn't be used.
Characteristics ~ No Side Effects:
- Side effects are lies.
- Our function promises to do one thing, but it does other hidden things.
Functions
Characteristics ~ Duplicate:
- Don’t Repeat yourself.
Dry Principle.
- Duplication may be the root of all evil in a software.
Do one thing
public bool IsEdible()
{
if (this.ExpirationDate > DateTime.Now &&
this.ApprovedForConsumption == true &&
this.InspectorId != null)
{
return true;
}
else
{
return false;
}
}
How many things is the function doing?
● check expiration
● check approval
● check inspection
● answer the request
Do one thing
public bool IsEdible()
{
return IsFresh() && IsApproved() && IsInspected();
}
Now the function is doing one thing!
A change in the specifications turns into a single change in
the code!
Don’t mix levels of abstraction
public void DoTheDomesticThings()
{
TakeOutTheTrash();
WalkTheDog();
for (Dish dish : dirtyDishStack)
{
Sink.washDish(dish);
teaTowel.DryDish(dish);
}
}
public void DoTheDomesticThings()
{
TakeOutTheTrash();
WalkTheDog();
DoTheDishes();
}
Which one is easier to read and understand?
One Level of Abstraction per Function
Separate commands and queries
Commands should only do
something (One thing)
public class Car
{
private bool isOn;
public void turnOn()
{
isOn = true;
}
public bool isOn()
{
return isOn;
}
}
Queries should only
answer something
AVOID SIDE EFFECTS!
Use exceptions
public int Foo()
{
…
}
public void Bar()
{
if (Foo() == OK)
{
…
} else {
//error handling
}
}
Errors have to be encoded
Checks (when performed) require a lot
of code
It’s harder to extend such programs
Use exceptions
public void foo()
{
throws FooException{
…
}
}
public void bar()
{
try {
foo();
…
}catch (FooException)
{
//error handling
}
}
No need to mix return values and
control values
Cleaner syntax
Easier to extend
Don’t Repeat Yourself
Public void bar () {
foo(“A”);
foo(“B”);
foo(“C”);
}
public void bar()
{
string[] elements = {“A”, “B”, “C”};
for (string element : elements)
{
foo(element);
}
}
DO NOT EVER COPY AND PASTE CODE
Logic to handle the elements it’s
written once for all
Comments
● Nothing can be quite so helpful as a well-placed comment.
● Nothing can clutter up a module more than useless and outdated comments.
● Comment are always failures.
● we must have them because we cannot figure out how to express ourselves in code.
● Comments lie. Not always, and not intentionally, but too often.
● The older a comment is, the farther away it is from the code it describes.
● Programmers cannot realistically maintain them.
Comments
● Inaccurate comments are far worse than no comments at all. They delude and mislead.
● Only the code can truly tell you what it does.
● It is the only source of truly accurate information.
● Comments are sometimes necessary, but we should spend significant time trying to minimize
them
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
if (employee.isEligibleForFullBenefits())
Good Comments
- Legal comments: Sometimes our corporate coding standards force to write
certain comments for legal reasons.
- Informative Comments: It is sometimes useful to provide basic information with
comment.
Good Comments
- Explanation of Intent: Sometimes a comment goes beyond just useful information
about the implementation and provides the intent behind a decision.
- Clarification: Sometimes it is just helpful to translate the meaning of some obscure
argument or return value into something that’s readable.
Good Comments
- Warning of Consequences: Sometimes it is useful to warn other programmers
about certain consequences.
- TODO: It is sometimes reasonable to leave "To do" notesin the form of //TODO
comments. Don't leave it for long, go through them and try to clean.
Bad Comments
- Mumbling: Writing comments just because you feel you should or because the
process require it, is not at all correct.
Bad Comments
- Redundant Comments: The comments tell exactly the same thing as the code
does.
- Noise Comments: They restate the obvious and provide no new information.
Bad Comments
- Journal Comments: Sometimes people add a comment to the start of a module
every time they edit it. Use a version controlling system(e.g. git) where author, time,
etc stays record.
Bad Comments
- Position Markers: Sometimes Programmers like to mark a particular position in a
source file. In rare cases in makes sense to gather certain functions together
beneath a banner. In general they are clutter that should be eliminated.
- Commented-Out Code: If you don't need them, delete them. Creates code rot.
Objects and Data Structures : Data Abstraction
- Abstraction focuses on the observable behavior an object.
- Abstraction is used as both process and an entity.
- Abstraction, as a process, denotes the extracting of the essential details about an
item, or a group of items, while ignoring the inessential details.
- Abstraction as an entity, denotes a model, a view, or some other focused
representation for an actual item.
Objects and Data Structures : Data/Object
- Objects hide their data behind abstractions and expose functions that operate on that data.
- Data structure expose their data and have no meaningful functions.
- When to use what?
- When we want to add new data types rather than new functions - objects will be more appropriate.
- When we want to add new functions as opposed to data types - data structures will be more
appropriate.
- Everything is an object is a myth.
- Sometimes simple data structures with produces operating on them are much easier.
Objects and Data Structures : The Law of Demeter
- It Says that a method M of object O can access/invoke methods of:
- O itself
- M's input arguments
- Any object created in M
- O's instance variables
- Each unit (method) should have limited knowledge about other units.
- A member should not know about the innards of the objects it manipulates.
- Metaphor: Suppose I bye something at Shopno. When I need to pay, will I give my wallet to the
salesmen so he will open it and get the money out ? Or, I give him the money directly ?
Objects and Data Structures : The Law of Demeter
- When LoD might be violated: when you need to use more than 1 dot in a statement.
- How to maintain LoD:
- Don't let the inner workings of an object be known to its caller.
- Prevent the parent from having to walk the dependency chain through the child objects.
- Benefits for following LoD: maintainable, reusable, modularized and less coupled code.
Message chains
a.GetB().GetC().GetD().GetTheNeededData()
a.GetTheNeededData()
Law of Demeter: Each unit should
only talk with friends
Classes : Organization
- Should begin with a list of variable.
- Public static constants (if any) should come first.
- Private static variables.
- Private instance variables.
- Public functions.
- Private utility functions called by a public function should be placed right after it.
- Try to keep the variables and utility functions private, at max protected, but not public.
Classes : Characteristics
- Should be small. How small ?
- Count its responsibilities.
- Try to describe the class in around 25 words without using the words "if", "and", "or", "but".
- Classes should have one responsibility - only one reason to change.
Single Responsibility Principle(SRP)
- We want out systems to be composed of many small classes, not a few large ones.
- Each small class encapsulates a single responsibility, has a single reason to change.
- Each one collaborates with a few others to achieve the desired system behaviors.
Classes : Characteristics
- Should have a small number of instance variables.
- Each of the methods of a class should manipulate one or more of those variables.
- The more variables a method manipulates the more cohesive that method is to its class.
- When classes lose cohesion, split them.
Classes : Organizing for change
- Every Change subjects us to the risk that the remainder of the system no longer works as
intended.
- In a clean system we organize our classes so as to reduce the risk of change.
- As soon as we find ourselves opening up a class, we should consider fixing our design.
- Classes should be open for extension but closed for modification.
Open-Closed Principle.
Classes : Organizing for change
- Needs will change, therefore code will change.
- A Client class depending upon concrete details is at risk when those details change.
- We can introduce interfaces and abstract classes to isolate the impact.
- We need to minimize the coupling.
- Classes should depend upon abstractions, not on concrete details.
Dependency Inversion Principle.
Other code smells
What we don’t want to see in your code
The bloaters
Something in your code grow too large
Long methods and large
classes
Primitive obsession and
too much parameters
Single responsibility
principle violated
It is a symptom of bad
design
Primitive obsession
public class Car
{
private int red, green, blue;
public void paint(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
}
public class Car
{
private Color color;
public void paint(Color color)
{
this.color = color;
}
}
The OO abusers
Object orientation is not fully exploited
Switch statements on
objects
Refused bequest
Alternative classes with
different interfaces
It is better to use
polymorphism
Poor class hierarchy design
Switch vs polymorphism
public Money calculatePay(Employee e)
{
switch (e.type)
{
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeException(e.type);
} }
public abstract class Employee
{
public abstract Money calculatePay();
}
Refused bequest
Subclass doesn’t use superclass methods and attributes
public abstract class Employee
{
private int quota;
public int GetQuota();
...
}
public class Salesman : Employee{ ... }
public class Engineer : Employee{
...
public int GetQuota()
{
throw new NotSupportedException();
}
}
Engineer does not use quota. It
should be pushed down to
Salesman
The change preventers
Something is making hard to change the code
Divergent change A class has to be changed in
several parts
Shotgun surgery A single change requires
changes in several classes
The dispensables
The code contains something unnecessary
A class is not doing enough Class not providing logic
Unused or redundant code It isn’t something useful
The couplers
Some classes are too tightly coupled
Feature Envy Misplaced responsibility
Inappropriate Intimacy
Classes should know as little as
possible about each other
Message Chains
Too complex data access
Feature Envy
public class Customer
{
private PhoneNumber mobilePhone;
public string GetMobilePhoneNumber()
{
return “(” +
mobilePhone.GetAreaCode() + “)” + mobilePhone.GetPrefix() + “-” + mobilePhone.GetNumber();
}
}
public string GetMobilePhoneNumber(){
return mobilePhone.ToFormattedString();
}
Error Handling
Exceptions vs Error Codes:
- The problem with error code approach is that they clutter the caller.
- The caller must check for errors immediately after the call.
- It is better to throw an exception when you encounter an error.
- The calling code is cleaner. Its logic is not obscured by error handling.
Error Handling
Context with exceptions:
- Each exception that you throw should provide enough context to determine the source and location of
an error.
- Create informative error messages and pass them along with exceptions.
- Mention the operation that failed and the type of failure.
Error Handling
Don’t Return null:
- When we return null, we are essentially creating work for ourselves.
- One missing null check to send an application spinning out of control.
- If your method returns a list, try to return an empty list instead of null.
- If your method returns an object, try to return a special object that shares the same interface, or throw an
exception.
- This will minimize the chance of NullPointerExceptions and your code will be better.
Error Handling
Don’t pass null:
- Returning null from methods is bad, but passing null into methods is worse.
- If you are working with an API which expects you to pass null, than its ok.
- Otherwise, you should avoid passing null in your code whenever possible.
Error Handling
Don’t pass null:
Unit Tests : The Three Laws of TDD
First law
- You may not write production code until
- You have written a failing unit test
Second law
- You may not write more of a unit test
- Than is sufficient to fail, and not compiling is failing
Third law
- You may not write more production code
- Than is sufficient to pass the currently failing test
Unit Tests
Keeping Tests Clean
- Test code is just as important as production code
Clean Tests
- What makes a clean test? three things
- Readability, readability, and readability
Unit Tests
One Assert per Test
- Tests come to a single conclusion
- That is quick and easy to understand
Single Concept per Test
- The best rule is that you should
- Minimize the number of asserts per concept and
- Test just one concept per test function
Unit Tests
F.I.R.S.T:
❖ Fast
❖ Independent
❖ Repeatable
❖ Self-validating
❖ Timely
Formatting
- Code should be nicely formatted.
- Shows our care and professionalism.
- Choosing a set of simple rules for formatting and always following them.
- IDE can help apply the formatting rules.
Formatting - Vertical
- Our source file should be like a newspaper article.
- The name should be simple and self explanatory.
- Top parts should provider the top level concepts.
- Details should increase as we move down.
- At the end we find the low level functions and details of the file.
Formatting - Vertical
Openness:
- Almost all code are read left to right and top to bottom.
- Each line represents an expression.
- Each group of lines represents a complete thought.
- Those thoughts should be separated from each other with blank lines.
Formatting - Vertical
Density:
- Vertical density implies close association.
- Lines of code that are tightly related should appear vertically dense/close.
Formatting - Vertical
Distance:
- Concepts that are closely related should be kept vertically close to each other.
- This rule doesn't work for concepts that belong in separate files.
- The vertical separation should tell us how important each is to other.
- Variable should be declared as close to their usage as possible.
- Local variables should appear a the top of each function.
- Control variables for loops should usually be declared within the loop statement.
- Instance variables should be declared at the top of the class.
- If one function calls another function they should be close to each other.
- The caller function should be above the callee function if possible.
Formatting - Vertical
Ordering:
- The most important concepts should come first.
- The low-level details to come last
Formatting - Horizontal
Openness and Density:
- Horizontal white space is used to associate things that are strongly related and disassociate things are more
weakly related.
- Surround the assignment operators with white space.
- No spaces between the function names and the opening parenthesis.
- Separate arguments within the function call parentheses.
Formatting - Horizontal
Horizontal Alignment:
before
Formatting - Horizontal
Horizontal Alignment:
After
Formatting - Team Rules
- Every programmer has his own favorite formatting rules
- But if he works in a team
- Then the team rules
Emergence
Resource
Clean code and code smells
Clean code and code smells

More Related Content

What's hot (20)

PDF
Clean code
Arturo Herrero
 
PPTX
Clean Code Principles
YeurDreamin'
 
KEY
Clean Code
Hendrik Ebel
 
PDF
Clean coding-practices
John Ferguson Smart Limited
 
PDF
Clean code
Achintya Kumar
 
PPTX
Clean code
ifnu bima
 
PPTX
Clean Code I - Best Practices
Theo Jungeblut
 
PPTX
The Art of Clean code
Victor Rentea
 
PPTX
Clean code
Duc Nguyen Quang
 
PDF
Clean code: meaningful Name
nahid035
 
PPTX
Presentation on C++ Programming Language
satvirsandhu9
 
PPTX
Clean Code
Victor Rentea
 
PPTX
Clean Code
swaraj Patil
 
PPTX
Constructor and destructor
Shubham Vishwambhar
 
PPTX
Polymorphism in java
sureshraj43
 
PPTX
Clean code
Henrique Smoco
 
PDF
Python programming : List and tuples
Emertxe Information Technologies Pvt Ltd
 
PPTX
Loops in java script
Ravi Bhadauria
 
PPTX
Exception Handling in object oriented programming using C++
Janki Shah
 
PPT
Shell sort
Rajendran
 
Clean code
Arturo Herrero
 
Clean Code Principles
YeurDreamin'
 
Clean Code
Hendrik Ebel
 
Clean coding-practices
John Ferguson Smart Limited
 
Clean code
Achintya Kumar
 
Clean code
ifnu bima
 
Clean Code I - Best Practices
Theo Jungeblut
 
The Art of Clean code
Victor Rentea
 
Clean code
Duc Nguyen Quang
 
Clean code: meaningful Name
nahid035
 
Presentation on C++ Programming Language
satvirsandhu9
 
Clean Code
Victor Rentea
 
Clean Code
swaraj Patil
 
Constructor and destructor
Shubham Vishwambhar
 
Polymorphism in java
sureshraj43
 
Clean code
Henrique Smoco
 
Python programming : List and tuples
Emertxe Information Technologies Pvt Ltd
 
Loops in java script
Ravi Bhadauria
 
Exception Handling in object oriented programming using C++
Janki Shah
 
Shell sort
Rajendran
 

Similar to Clean code and code smells (20)

PDF
Clean Code
Chris Farrell
 
PPTX
Clean code - DSC DYPCOE
Patil Shreyas
 
PPT
Clean code
Uday Pratap Singh
 
PPTX
Principled And Clean Coding
Metin Ogurlu
 
PDF
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
DevDay Da Nang
 
PPTX
Clean Code - Writing code for human
NETKO Solution
 
PPT
Coding Standards
Jeevitesh Ms
 
PPTX
CLEAN CODING AND DEVOPS Final.pptx
JEEVANANTHAMG6
 
PPTX
Best-Practices-in-Writing-Clean-Maintainable-Code
Ozias Rondon
 
PPTX
Clean code, Feb 2012
cobyst
 
PPTX
Clean Code
Nascenia IT
 
PDF
Clean code
Khou Suylong
 
PPT
Clean Code summary
Jan de Vries
 
PPTX
Clean code
Simon Sönnby
 
PDF
UNIT I cloud computing ppt cloud ccd all about the cloud computing
vishnubala78900
 
PPTX
C# coding standards, good programming principles & refactoring
Eyob Lube
 
PPTX
Improving Code Quality Through Effective Review Process
Dr. Syed Hassan Amin
 
PDF
Agileee Developers Toolkit In The Agile World
Agileee
 
PDF
Clean Code. An Agile Guide to Software Craft Kameron H.
komvjzfjj621
 
PPTX
Clean code presentation
Bhavin Gandhi
 
Clean Code
Chris Farrell
 
Clean code - DSC DYPCOE
Patil Shreyas
 
Clean code
Uday Pratap Singh
 
Principled And Clean Coding
Metin Ogurlu
 
[DevDay2018] Let’s all get along. Clean Code please! - By: Christophe K. Ngo,...
DevDay Da Nang
 
Clean Code - Writing code for human
NETKO Solution
 
Coding Standards
Jeevitesh Ms
 
CLEAN CODING AND DEVOPS Final.pptx
JEEVANANTHAMG6
 
Best-Practices-in-Writing-Clean-Maintainable-Code
Ozias Rondon
 
Clean code, Feb 2012
cobyst
 
Clean Code
Nascenia IT
 
Clean code
Khou Suylong
 
Clean Code summary
Jan de Vries
 
Clean code
Simon Sönnby
 
UNIT I cloud computing ppt cloud ccd all about the cloud computing
vishnubala78900
 
C# coding standards, good programming principles & refactoring
Eyob Lube
 
Improving Code Quality Through Effective Review Process
Dr. Syed Hassan Amin
 
Agileee Developers Toolkit In The Agile World
Agileee
 
Clean Code. An Agile Guide to Software Craft Kameron H.
komvjzfjj621
 
Clean code presentation
Bhavin Gandhi
 
Ad

Recently uploaded (20)

PPTX
Introduction to Fluid and Thermal Engineering
Avesahemad Husainy
 
PPTX
filteration _ pre.pptx 11111110001.pptx
awasthivaibhav825
 
PPTX
MSME 4.0 Template idea hackathon pdf to understand
alaudeenaarish
 
PDF
Packaging Tips for Stainless Steel Tubes and Pipes
heavymetalsandtubes
 
PPTX
sunil mishra pptmmmmmmmmmmmmmmmmmmmmmmmmm
singhamit111
 
PPTX
MULTI LEVEL DATA TRACKING USING COOJA.pptx
dollysharma12ab
 
PPTX
Water resources Engineering GIS KRT.pptx
Krunal Thanki
 
PDF
Introduction to Ship Engine Room Systems.pdf
Mahmoud Moghtaderi
 
PPTX
ETP Presentation(1000m3 Small ETP For Power Plant and industry
MD Azharul Islam
 
PDF
2010_Book_EnvironmentalBioengineering (1).pdf
EmilianoRodriguezTll
 
PDF
Zero Carbon Building Performance standard
BassemOsman1
 
PDF
SG1-ALM-MS-EL-30-0008 (00) MS - Isolators and disconnecting switches.pdf
djiceramil
 
PDF
Machine Learning All topics Covers In This Single Slides
AmritTiwari19
 
PPTX
Online Cab Booking and Management System.pptx
diptipaneri80
 
PPTX
Chapter_Seven_Construction_Reliability_Elective_III_Msc CM
SubashKumarBhattarai
 
PDF
67243-Cooling and Heating & Calculation.pdf
DHAKA POLYTECHNIC
 
PDF
STUDY OF NOVEL CHANNEL MATERIALS USING III-V COMPOUNDS WITH VARIOUS GATE DIEL...
ijoejnl
 
PPTX
FUNDAMENTALS OF ELECTRIC VEHICLES UNIT-1
MikkiliSuresh
 
DOCX
SAR - EEEfdfdsdasdsdasdasdasdasdasdasdasda.docx
Kanimozhi676285
 
PPTX
Basics of Auto Computer Aided Drafting .pptx
Krunal Thanki
 
Introduction to Fluid and Thermal Engineering
Avesahemad Husainy
 
filteration _ pre.pptx 11111110001.pptx
awasthivaibhav825
 
MSME 4.0 Template idea hackathon pdf to understand
alaudeenaarish
 
Packaging Tips for Stainless Steel Tubes and Pipes
heavymetalsandtubes
 
sunil mishra pptmmmmmmmmmmmmmmmmmmmmmmmmm
singhamit111
 
MULTI LEVEL DATA TRACKING USING COOJA.pptx
dollysharma12ab
 
Water resources Engineering GIS KRT.pptx
Krunal Thanki
 
Introduction to Ship Engine Room Systems.pdf
Mahmoud Moghtaderi
 
ETP Presentation(1000m3 Small ETP For Power Plant and industry
MD Azharul Islam
 
2010_Book_EnvironmentalBioengineering (1).pdf
EmilianoRodriguezTll
 
Zero Carbon Building Performance standard
BassemOsman1
 
SG1-ALM-MS-EL-30-0008 (00) MS - Isolators and disconnecting switches.pdf
djiceramil
 
Machine Learning All topics Covers In This Single Slides
AmritTiwari19
 
Online Cab Booking and Management System.pptx
diptipaneri80
 
Chapter_Seven_Construction_Reliability_Elective_III_Msc CM
SubashKumarBhattarai
 
67243-Cooling and Heating & Calculation.pdf
DHAKA POLYTECHNIC
 
STUDY OF NOVEL CHANNEL MATERIALS USING III-V COMPOUNDS WITH VARIOUS GATE DIEL...
ijoejnl
 
FUNDAMENTALS OF ELECTRIC VEHICLES UNIT-1
MikkiliSuresh
 
SAR - EEEfdfdsdasdsdasdasdasdasdasdasdasda.docx
Kanimozhi676285
 
Basics of Auto Computer Aided Drafting .pptx
Krunal Thanki
 
Ad

Clean code and code smells

  • 1. Clean Code and Code Smells Md Aftab Uddin Kajal Software Engineer SELISE rockin' software
  • 2. WANT TO BE BETTER “You are reading this book for two reasons. First, you are a programmer. Second, you want to be a better programmer. We need better programmers.” -- ROBERT C. MARTIN
  • 3. The Boy Scout Rule Robert C. Martin Uncle Bob
  • 4. Elegance I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well. -- Bjarne Stroustrup
  • 5. Simple, direct, prose Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control. Grady Booch
  • 6. Literate Clean code can be read, and enhanced by a developer other than its original author. It has unit and acceptance tests. It has meaningful names. It provides one way rather than many ways for doing one thing. It has minimal dependencies, which are explicitly defined, and provides a clear and minimal API. Code should be literate since depending on the language, not all necessary information can be expressed clearly in code alone. -- Dave Thomas
  • 7. Care Clean code always looks like it was written by someone who cares Michael Feathers
  • 8. Small, expressive, simple Reduced duplication, high expressiveness, and early building of, simple abstractions Ron Jeffries
  • 9. What you expected You know you are working on clean code when each routine you reads turns out to be pretty much what you expected -- Ward Cunningham
  • 11. Clean and Bad Code Bad Code: - We all have seen bad code/code smells. - We have all written bad code. - How can we written bad code? - If it doesn't work - that's bad. - But what if it works? - compiles, run and produces the expected output.
  • 12. Clean and Bad Code Bad Code: - Most of the times for the clients output is good enough. - But as professionals we know that's not enough. - We don't do justice to us or our clients if we are just satisfied with a code that's just working. - Scenario: We had a deadline, we needed to get the job done so we have written some bad code. The client is happy with the end result, and doesn't get by the bad code. After few days, client wants us to do a small change, and since it's small he gives us a very short deadline. We are confident we can do it, So start coding. it turns out that, because of our bad coding, we now need to make changes a lot of places to add the new change. This is giving us a headache. And the client now doesn't understand why it is taking us so long to make a small change, he is no longer happy.
  • 13. Clean and Bad Code Clean Code: - It's not enough to write code well. - The code has to be kept clean over time. - We have all seen code rot and degrade as time passes. - Leave the campground cleaner than you found it. The Boy Scout Rule
  • 15. A simple example What does it mean? Days? Diameter? ...int d; Is this any better?int d; //elapsed time in days What about this? int elapsedTimeInDays;
  • 16. A simple example public List<int[]> GetThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x in theList){ if (x[0] == 4) list1.add(x); } return list1; } This code is quite simple but what does it do? Looking at it we can’t tell what it is actually doing!
  • 17. A simple example public List<int[]> GetFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell in gameBoard){ if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(x); } return flaggedCells; } Is this code any better?
  • 18. A simple example public List<Cell> GetFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell in gameBoard){ if (cell.isFlagged()) flaggedCells.add(x); } return flaggedCells; } What about this?
  • 19. A simple example What we have done: flaggedCells rather than list1 used intention revealing names cell[STATUS_VALUE] rather than x[0]replaced magic numbers with constants Cell cell rather than int[] cellcreated an appropriate abstract data type
  • 20. Meaningful Names int a = l; if (O == l){ a = O1; }else{ l = 01; } Avoid Disinformation public static void CopyChars(char a1[], char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } } Make Meaningful Distinctions
  • 21. Meaningful Names class DtaRcrd102 { private DateTime genymdhms; private DateTime modymdhms; private string pszqint = "102"; /* ... */ } Use Pronounceable Names class Customer { private DateTime generationTimestamp; private DateTime modificationTimestamp; private String recordId = "102"; /* ... */ }
  • 22. Meaningful Names for (int j = 0; j< 34; j++) { s += (t[j] * 4) / 5; } Use Searchable Names
  • 23. Meaningful Names int realDaysPerIdealDay = 4; const int WORK_DAYS_PER_WEEK = 5; int sum = 0; for (int j = 0; j<NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; } Use Searchable Names
  • 24. Meaningful Names Member Prefixes (Avoid encodings) public class Part{ public string m_dsc{get; set;} } public class Part{ public string Description{get; set;} }
  • 25. Meaningful Names Hungarian Notation (Avoid encodings) PhoneNumber phoneString; // name not changed when type changed! PhoneNumber phone;
  • 26. Meaningful Names for (a = 0; a < 10; a++) for (b = 0; b < 10; b++) Avoid Mental Mapping
  • 27. Meaningful Names Manager, Processor, Data, Info Class Names Customer, WikiPage, Account, AddressParser // a class name should not be a verb Classes and objects should have noun or noun phrase names
  • 28. Meaningful Names Method Names Methods should have verb or verb phrase names like PostPayment, DeletePage, or Save
  • 29. Meaningful Names Pick One Word per Concept Fetch, Retrieve, Get // as equivalent methods Controller, Manager, Driver // confusing
  • 30. Meaningful Names Use Solution Domain Names AccountVisitor, JobQueue // people who read your code will be programmers Add Meaningful Context firstName, lastName, street, city, state, zipcode // a better solution addrFirstName, addrLastName, addrState // a better solution Class Address
  • 31. Meaningful Names Don’t Add Gratuitous Context Address // is a fine name for a class AccountAddress, CustomerAddress // are fine names for instances of the class Address // but could be poor names for classes MAC addresses, port addresses, Web addresses // a better solution PostalAddress, MAC, URI
  • 32. Functions Characteristics ~ Size: - Should be small. How small ? - Each should be Two/Three/Four lines, by not sacrificing readability. - Each should be transparently obvious. - Each should be tell a story. - They Should be not be large enough to hold too many nested structures. - The indent level of a function should not be greater than one or two.
  • 33. Functions Characteristics ~ One Thing: - Should only do one thing. - Should do that thing well. - How to find whether a function is doing more than one thing? - If we can extract another function from it with a name that is not merely a restatement of its implementation. - Functions that do only one thing, cannot be divided into sections.
  • 34. Functions Characteristics ~ Abstraction: - One level of abstraction. - Mixing levels of abstraction within a function will be confusing for the reader. - Every function should be followed by those at the next level of abstraction. Step Down Rule. - Function should change the state of an object, or it should return some information about that object. Doing both often leads to confusion.
  • 35. Functions Characteristics ~ Names: - User descriptive name - Don't be afraid to make a name long. - Don’t be afraid to spend time choosing a name. - Try several different names and read the code to see whether the name fits or not.
  • 36. Functions Characteristics ~ Arguments: - Ideal number of arguments for a function is zero. - Next comes one. - Followed by two. - Three arguments should be avoided where possible. - More than three requires very special justification and shouldn't be used. Characteristics ~ No Side Effects: - Side effects are lies. - Our function promises to do one thing, but it does other hidden things.
  • 37. Functions Characteristics ~ Duplicate: - Don’t Repeat yourself. Dry Principle. - Duplication may be the root of all evil in a software.
  • 38. Do one thing public bool IsEdible() { if (this.ExpirationDate > DateTime.Now && this.ApprovedForConsumption == true && this.InspectorId != null) { return true; } else { return false; } } How many things is the function doing? ● check expiration ● check approval ● check inspection ● answer the request
  • 39. Do one thing public bool IsEdible() { return IsFresh() && IsApproved() && IsInspected(); } Now the function is doing one thing! A change in the specifications turns into a single change in the code!
  • 40. Don’t mix levels of abstraction public void DoTheDomesticThings() { TakeOutTheTrash(); WalkTheDog(); for (Dish dish : dirtyDishStack) { Sink.washDish(dish); teaTowel.DryDish(dish); } } public void DoTheDomesticThings() { TakeOutTheTrash(); WalkTheDog(); DoTheDishes(); } Which one is easier to read and understand? One Level of Abstraction per Function
  • 41. Separate commands and queries Commands should only do something (One thing) public class Car { private bool isOn; public void turnOn() { isOn = true; } public bool isOn() { return isOn; } } Queries should only answer something AVOID SIDE EFFECTS!
  • 42. Use exceptions public int Foo() { … } public void Bar() { if (Foo() == OK) { … } else { //error handling } } Errors have to be encoded Checks (when performed) require a lot of code It’s harder to extend such programs
  • 43. Use exceptions public void foo() { throws FooException{ … } } public void bar() { try { foo(); … }catch (FooException) { //error handling } } No need to mix return values and control values Cleaner syntax Easier to extend
  • 44. Don’t Repeat Yourself Public void bar () { foo(“A”); foo(“B”); foo(“C”); } public void bar() { string[] elements = {“A”, “B”, “C”}; for (string element : elements) { foo(element); } } DO NOT EVER COPY AND PASTE CODE Logic to handle the elements it’s written once for all
  • 45. Comments ● Nothing can be quite so helpful as a well-placed comment. ● Nothing can clutter up a module more than useless and outdated comments. ● Comment are always failures. ● we must have them because we cannot figure out how to express ourselves in code. ● Comments lie. Not always, and not intentionally, but too often. ● The older a comment is, the farther away it is from the code it describes. ● Programmers cannot realistically maintain them.
  • 46. Comments ● Inaccurate comments are far worse than no comments at all. They delude and mislead. ● Only the code can truly tell you what it does. ● It is the only source of truly accurate information. ● Comments are sometimes necessary, but we should spend significant time trying to minimize them // Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) if (employee.isEligibleForFullBenefits())
  • 47. Good Comments - Legal comments: Sometimes our corporate coding standards force to write certain comments for legal reasons. - Informative Comments: It is sometimes useful to provide basic information with comment.
  • 48. Good Comments - Explanation of Intent: Sometimes a comment goes beyond just useful information about the implementation and provides the intent behind a decision. - Clarification: Sometimes it is just helpful to translate the meaning of some obscure argument or return value into something that’s readable.
  • 49. Good Comments - Warning of Consequences: Sometimes it is useful to warn other programmers about certain consequences. - TODO: It is sometimes reasonable to leave "To do" notesin the form of //TODO comments. Don't leave it for long, go through them and try to clean.
  • 50. Bad Comments - Mumbling: Writing comments just because you feel you should or because the process require it, is not at all correct.
  • 51. Bad Comments - Redundant Comments: The comments tell exactly the same thing as the code does. - Noise Comments: They restate the obvious and provide no new information.
  • 52. Bad Comments - Journal Comments: Sometimes people add a comment to the start of a module every time they edit it. Use a version controlling system(e.g. git) where author, time, etc stays record.
  • 53. Bad Comments - Position Markers: Sometimes Programmers like to mark a particular position in a source file. In rare cases in makes sense to gather certain functions together beneath a banner. In general they are clutter that should be eliminated. - Commented-Out Code: If you don't need them, delete them. Creates code rot.
  • 54. Objects and Data Structures : Data Abstraction - Abstraction focuses on the observable behavior an object. - Abstraction is used as both process and an entity. - Abstraction, as a process, denotes the extracting of the essential details about an item, or a group of items, while ignoring the inessential details. - Abstraction as an entity, denotes a model, a view, or some other focused representation for an actual item.
  • 55. Objects and Data Structures : Data/Object - Objects hide their data behind abstractions and expose functions that operate on that data. - Data structure expose their data and have no meaningful functions. - When to use what? - When we want to add new data types rather than new functions - objects will be more appropriate. - When we want to add new functions as opposed to data types - data structures will be more appropriate. - Everything is an object is a myth. - Sometimes simple data structures with produces operating on them are much easier.
  • 56. Objects and Data Structures : The Law of Demeter - It Says that a method M of object O can access/invoke methods of: - O itself - M's input arguments - Any object created in M - O's instance variables - Each unit (method) should have limited knowledge about other units. - A member should not know about the innards of the objects it manipulates. - Metaphor: Suppose I bye something at Shopno. When I need to pay, will I give my wallet to the salesmen so he will open it and get the money out ? Or, I give him the money directly ?
  • 57. Objects and Data Structures : The Law of Demeter - When LoD might be violated: when you need to use more than 1 dot in a statement. - How to maintain LoD: - Don't let the inner workings of an object be known to its caller. - Prevent the parent from having to walk the dependency chain through the child objects. - Benefits for following LoD: maintainable, reusable, modularized and less coupled code.
  • 59. Classes : Organization - Should begin with a list of variable. - Public static constants (if any) should come first. - Private static variables. - Private instance variables. - Public functions. - Private utility functions called by a public function should be placed right after it. - Try to keep the variables and utility functions private, at max protected, but not public.
  • 60. Classes : Characteristics - Should be small. How small ? - Count its responsibilities. - Try to describe the class in around 25 words without using the words "if", "and", "or", "but". - Classes should have one responsibility - only one reason to change. Single Responsibility Principle(SRP) - We want out systems to be composed of many small classes, not a few large ones. - Each small class encapsulates a single responsibility, has a single reason to change. - Each one collaborates with a few others to achieve the desired system behaviors.
  • 61. Classes : Characteristics - Should have a small number of instance variables. - Each of the methods of a class should manipulate one or more of those variables. - The more variables a method manipulates the more cohesive that method is to its class. - When classes lose cohesion, split them.
  • 62. Classes : Organizing for change - Every Change subjects us to the risk that the remainder of the system no longer works as intended. - In a clean system we organize our classes so as to reduce the risk of change. - As soon as we find ourselves opening up a class, we should consider fixing our design. - Classes should be open for extension but closed for modification. Open-Closed Principle.
  • 63. Classes : Organizing for change - Needs will change, therefore code will change. - A Client class depending upon concrete details is at risk when those details change. - We can introduce interfaces and abstract classes to isolate the impact. - We need to minimize the coupling. - Classes should depend upon abstractions, not on concrete details. Dependency Inversion Principle.
  • 64. Other code smells What we don’t want to see in your code
  • 65. The bloaters Something in your code grow too large Long methods and large classes Primitive obsession and too much parameters Single responsibility principle violated It is a symptom of bad design
  • 66. Primitive obsession public class Car { private int red, green, blue; public void paint(int red, int green, int blue) { this.red = red; this.green = green; this.blue = blue; } } public class Car { private Color color; public void paint(Color color) { this.color = color; } }
  • 67. The OO abusers Object orientation is not fully exploited Switch statements on objects Refused bequest Alternative classes with different interfaces It is better to use polymorphism Poor class hierarchy design
  • 68. Switch vs polymorphism public Money calculatePay(Employee e) { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeException(e.type); } } public abstract class Employee { public abstract Money calculatePay(); }
  • 69. Refused bequest Subclass doesn’t use superclass methods and attributes public abstract class Employee { private int quota; public int GetQuota(); ... } public class Salesman : Employee{ ... } public class Engineer : Employee{ ... public int GetQuota() { throw new NotSupportedException(); } } Engineer does not use quota. It should be pushed down to Salesman
  • 70. The change preventers Something is making hard to change the code Divergent change A class has to be changed in several parts Shotgun surgery A single change requires changes in several classes
  • 71. The dispensables The code contains something unnecessary A class is not doing enough Class not providing logic Unused or redundant code It isn’t something useful
  • 72. The couplers Some classes are too tightly coupled Feature Envy Misplaced responsibility Inappropriate Intimacy Classes should know as little as possible about each other Message Chains Too complex data access
  • 73. Feature Envy public class Customer { private PhoneNumber mobilePhone; public string GetMobilePhoneNumber() { return “(” + mobilePhone.GetAreaCode() + “)” + mobilePhone.GetPrefix() + “-” + mobilePhone.GetNumber(); } } public string GetMobilePhoneNumber(){ return mobilePhone.ToFormattedString(); }
  • 74. Error Handling Exceptions vs Error Codes: - The problem with error code approach is that they clutter the caller. - The caller must check for errors immediately after the call. - It is better to throw an exception when you encounter an error. - The calling code is cleaner. Its logic is not obscured by error handling.
  • 75. Error Handling Context with exceptions: - Each exception that you throw should provide enough context to determine the source and location of an error. - Create informative error messages and pass them along with exceptions. - Mention the operation that failed and the type of failure.
  • 76. Error Handling Don’t Return null: - When we return null, we are essentially creating work for ourselves. - One missing null check to send an application spinning out of control. - If your method returns a list, try to return an empty list instead of null. - If your method returns an object, try to return a special object that shares the same interface, or throw an exception. - This will minimize the chance of NullPointerExceptions and your code will be better.
  • 77. Error Handling Don’t pass null: - Returning null from methods is bad, but passing null into methods is worse. - If you are working with an API which expects you to pass null, than its ok. - Otherwise, you should avoid passing null in your code whenever possible.
  • 79. Unit Tests : The Three Laws of TDD First law - You may not write production code until - You have written a failing unit test Second law - You may not write more of a unit test - Than is sufficient to fail, and not compiling is failing Third law - You may not write more production code - Than is sufficient to pass the currently failing test
  • 80. Unit Tests Keeping Tests Clean - Test code is just as important as production code Clean Tests - What makes a clean test? three things - Readability, readability, and readability
  • 81. Unit Tests One Assert per Test - Tests come to a single conclusion - That is quick and easy to understand Single Concept per Test - The best rule is that you should - Minimize the number of asserts per concept and - Test just one concept per test function
  • 82. Unit Tests F.I.R.S.T: ❖ Fast ❖ Independent ❖ Repeatable ❖ Self-validating ❖ Timely
  • 83. Formatting - Code should be nicely formatted. - Shows our care and professionalism. - Choosing a set of simple rules for formatting and always following them. - IDE can help apply the formatting rules.
  • 84. Formatting - Vertical - Our source file should be like a newspaper article. - The name should be simple and self explanatory. - Top parts should provider the top level concepts. - Details should increase as we move down. - At the end we find the low level functions and details of the file.
  • 85. Formatting - Vertical Openness: - Almost all code are read left to right and top to bottom. - Each line represents an expression. - Each group of lines represents a complete thought. - Those thoughts should be separated from each other with blank lines.
  • 86. Formatting - Vertical Density: - Vertical density implies close association. - Lines of code that are tightly related should appear vertically dense/close.
  • 87. Formatting - Vertical Distance: - Concepts that are closely related should be kept vertically close to each other. - This rule doesn't work for concepts that belong in separate files. - The vertical separation should tell us how important each is to other. - Variable should be declared as close to their usage as possible. - Local variables should appear a the top of each function. - Control variables for loops should usually be declared within the loop statement. - Instance variables should be declared at the top of the class. - If one function calls another function they should be close to each other. - The caller function should be above the callee function if possible.
  • 88. Formatting - Vertical Ordering: - The most important concepts should come first. - The low-level details to come last
  • 89. Formatting - Horizontal Openness and Density: - Horizontal white space is used to associate things that are strongly related and disassociate things are more weakly related. - Surround the assignment operators with white space. - No spaces between the function names and the opening parenthesis. - Separate arguments within the function call parentheses.
  • 92. Formatting - Team Rules - Every programmer has his own favorite formatting rules - But if he works in a team - Then the team rules