SlideShare une entreprise Scribd logo
1  sur  36
by Dmytro Turskyi (March 2023)
(2008)
By Robert C. Martin (aka “Uncle Bob”)
Agenda
• Meaningful Names
• Functions
• Comments
• Error Handling
• Classes
• Environment
• General
Meaningful Names
• Avoid Mental Mapping
A single-letter name is a poor choice; it’s just a place holder that the reader
must mentally map to the actual concept. There can be no worse reason for
using the name “c” than because “a” and “b” were already taken.
• Method names
Methods should have verb or verb phrase names like postPayment,
deletePage, or save. Accessors, mutators, and predicates should be named
for their value and prefixed with get…, set…, and is…
Meaningful Names
• Use Searchable Names
const int WORK_DAYS_PER_WEEK = 5;
int realDaysPerIdealDay = 4;
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;
}
for (int j = 0; j < 34; j++) {
s += (t [ j ] * 4) / 5;
}
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
Meaningful Names
• Use Intention-Revealing Names
If a name requires a comment, then the name does not reveal its intent.
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<>();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
Meaningful Names
• Use Pronounceable Names
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;
private final String recordId = "102";
}
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
}
If you can’t pronounce it, you can’t
discuss it without sounding like an idiot.
Meaningful Names
• Class Names
Manager, Processor, Data, Info.
or
Meaningful Names
• Class Names
Customer, WikiPage, Account,
AddressParser.
Classes and objects should have noun or
noun phrase names and not include
indistinct noise words:
Manager, Processor, Data, Info.
Functions
• Small!
The first rule of functions is that they should be small.
Functions should hardly ever be ??? lines long.
Blocks within if statements, else statements, while statements, and so on
should be ??? long.
Functions
• Small!
The first rule of functions is that they should be small.
Functions should hardly ever be 20 lines long.
Blocks within if statements, else statements, while statements, and so on
should be one line long. Probably that line should be a function call.
• Do One Thing
To know that a function is doing more than “one thing” is if you can extract
another function from it with a name that is not merely a restatement of its
implementation.
Functions
• One Level of Abstraction per Function
We want the code to read like a top-down narrative.
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.
public String render() throws Exception {
StringBuffer html = new StringBuffer(“<hr");
if(size > 0)
html.append(" size="")
.append(size + 1).append(“”");
html.append(">");
return html.toString();
}
public String render() throws Exception {
HtmlTag hr = new HtmlTag(“hr");
if (extraDashes > 0)
hr.addAttribute(“size", hrSize(extraDashes));
return hr.html();
}
private String hrSize(int height) {
int hrSize = height + 1;
return String.format("%d", hrSize);
}
Functions
• Use Descriptive Names
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.
• Dependent Functions.
If one function calls another, they should be vertically close, and the caller
should be above the callee, if at all possible.
Functions
• Function Arguments
The ideal number of arguments for
a function is ??? .
includeSetupPageInto(newPageContent)
or
Functions
• Function Arguments
The ideal number of arguments for
a function is zero (niladic). Next
comes one (monadic), followed
closely by two (dyadic). Three
arguments (triadic) should be
avoided where possible.
includeSetupPage()
includeSetupPageInto(newPageContent)
Functions
• Flag Arguments
Flag arguments are ugly. Passing a
boolean into a function is a truly
terrible practice. It immediately
complicates the signature of the
method, loudly proclaiming that this
function does more than one thing. It
does one thing if the flag is true and
another if the flag is false!
render(boolean isSuite)
renderForSuite()
renderForSingleTest()
Functions
• Have No Side Effects
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(userName);
if (user != User.NULL) {
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
Functions
• Have No Side Effects
Side effects are lies.
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(userName);
if (user != User.NULL) {
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
checkPasswordAndInitializeSession
Functions
• Output Arguments
For example:
appendFooter(s);
Does this function append “s” as the
footer to something? Or does it
append some footer to “s”? Is “s” an
input or an output? It doesn’t take
long to look at the function
signature and see, but anything that
forces you to check the function
signature is equivalent to a double-
take. It’s a cognitive break and
should be avoided.
public void appendFooter(StringBuffer report)
report.appendFooter();
Comments
// Check to see if the employee is eligible
// for full benefits
if ((employee.flags & HOURLY_FLAG) &&
(employee.age > 65))
or
Comments
• Explain Yourself in Code
Only the code can truly tell you
what it does.
Comments are, at best, a
necessary evil.
Rather than spend your time writing
the comments that explain the
mess you’ve made, spend it
cleaning that mess.
Inaccurate comments are far worse
than no comments at all.
if (employee.isEligibleForFullBenefits())
// Check to see if the employee is eligible
// for full benefits
if ((employee.flags & HOURLY_FLAG) &&
(employee.age > 65))
Comments
• Legal Comments
Sometimes our corporate
coding standards force us to
write certain comments for
legal reasons.
// Copyright (C) 2003,2004,2005 by Object
// Mentor, Inc. All rights reserved.
// Released under the terms of the GNU
// General Public License version 2 or later.
• Explanation of Intent
Sometimes a comment goes
beyond just useful information
about the implementation and
provides the intent behind a
decision.
// This is our best attempt to get a race condition
// by creating large number of threads.
for (int i = 0; i < 25000; i++) {
WidgetBuilderThread widgetBuilderThread =
new WidgetBuilderThread(widgetBuilder, text, parent, failFlag);
Thread thread = new Thread(widgetBuilderThread);
thread.start();
}
Comments
• Warning of Consequences
Sometimes it is useful to warn
other programmers about
certain consequences.
public static SimpleDateFormat makeStandardHttpDateFormat() {
//SimpleDateFormat is not thread safe,
//so we need to create each instance independently.
SimpleDateFormat df =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
• TODO Comments
Nowadays, most good IDEs
provide special gestures and
features to locate all the //TODO
comments, so it’s not likely that
they will get lost.
//TODO-MdM these are not needed
// We expect this to go away when we do the
// checkout model
protected VersionInfo makeVersion() throws Exception{
return null;
}
Comments
• Amplification
A comment may be used to
amplify the importance of
something that may otherwise
seem inconsequential.
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognised
// as another list.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));
• Public APIs
There is nothing quite so helpful
and satisfying as a well-
described public API. It would
be difficult, at best, to write
programs without them.
/// dart doc comment
/**
* JavaDoc comment
*/
Comments
• Commented-Out Code
We’ve had good source code
control systems for a very long
time now. Those systems will
remember the code for us. We
don’t have to comment it out any
more. Just delete the code.
• Position Markers
In general they are clutter that
should be eliminated—
especially the noisy train of
slashes at the end. If you
overuse banners, they’ll fall into
the background noise and be
ignored.
// Actions //////////////////////////////////
InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(),
formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultsStream);
// response.setContent(reader.read(formatter.getByteCount()));
Error Handling
• Don’t Return Null
When we return null, we are
essentially creating work for
ourselves and foisting problems
upon our callers. All it takes is one
missing null check to send an
application spinning out of control.
List<Employee> employees = getEmployees();
if (employees != null) {
for (Employee e : employees) {
totalPay += e.getPay();
}
}
public List<Employee> getEmployees() {
if ( .. there are no employees .. )
return Collections.emptyList();
}
Error Handling
• Don’t Pass Null
In most programming languages
there is no way to deal with
a null that is passed by a caller
accidentally. Because this is the
case, the rational approach is to
forbid passing null by default. When
you do, you can code with the
knowledge that a null in an
argument list is an indication of a
problem, and end up with far fewer
careless mistakes.
calculator.xProjection(null, new Point(12, 13));
Classes
• Classes Should Be Small!
With functions we measured size by counting physical lines. With classes we use a
different measure. We count ???.
Classes
• Classes Should Be Small!
With functions we measured size by counting physical lines. With classes we use a
different measure. We count responsibilities.
The Single Responsibility Principle (SRP) states that a class or module should have
one, and only one, reason to change.
The name of a class should describe what responsibilities it fulfills. The more
ambiguous the class name, the more likely it has too many responsibilities.
The problem is that too many of us think that we are done once the program works.
We move on to the next problem rather than going back and breaking the
overstuffed classes into decoupled units with single responsibilities.
Classes
public class SuperDashboard extends JFrame implements MetaDataUser
public String getCustomizerLanguagePath()
public void setSystemConfigPath(String systemConfigPath)
public String getSystemConfigDocument()
public void setSystemConfigDocument(String systemConfigDocument)
public boolean getGuruState()
public boolean getNoviceState()
public boolean getOpenSourceState()
public void showObject(MetaObject object)
public void showProgress(String s)
public void setACowDragging(boolean allowDragging)
public boolean allowDragging()
public boolean isCustomizing()
public void setTitle(String title)
public IdeMenuBar getIdeMenuBar()
public void showHelper(MetaObject metaObject, String propertyName)
// ... many non-public methods follow ...
}
public class Version {
public int getMajorVersionNumber()
public int getMinorVersionNumber()
public int getBuildNumber()
}
Environment
• Build Requires More Than One Step
Building a project should be a single
trivial operation. You should not have to
check many little pieces out from source
code control. You should be able to
check out the system with one simple
command and then issue one other
simple command to build it.
svn get mySystem
cd mySystem
ant all
• Tests Require More Than One Step
You should be able to run all the unit tests with just one command. In the best
case you can run all the tests by clicking on one button in your IDE.
General
• Artificial Coupling
In general an artificial coupling is a coupling between two modules that serves no
direct purpose. It is a result of putting a variable, constant, or function in a temporarily
convenient, though inappropriate, location.
For example, general enumsshould not be contained within more specific classes
because this forces the whole application to know about these more specific classes.
The same goes for general purpose static functions being declared in specific
classes.
• Prefer Polymorphism to If/Else or Switch/Case
There may be no more than one switch statement for a given type of selection. The
cases in that switch statement must create polymorphic objects that take the place of
other such switch statements in the rest of the system.
General
• Replace Magic Numbers with Named Constants
In general it is a bad idea to have raw numbers in your code. You should hide them
behind well-named constants. The term “Magic Number” does not apply only to
numbers. It applies to any token that has a value that is not self-describing.
assertEquals(7777, Employee.find(“John Doe”).employeeNumber());
assertEquals(
HOURLY_EMPLOYEE_ID,
Employee.find(HOURLY_EMPLOYEE_NAME).employeeNumber());
General
• Encapsulate
Conditionals
Boolean logic is hard enough to
understand without having to
see it in the context of an if or
while statement. Extract
functions that explain the intent
of the conditional.
if (shouldBeDeleted(timer))
if (timer.hasExpired() &&
!timer.isRecurrent())
• Avoid Negative
Conditionals
Negatives are just a bit harder to
understand than positives. So,
when possible, conditionals
should be expressed as
positives.
if (buffer.shouldCompact())
if (!buffer.shouldNotCompact())
General
• Encapsulate Boundary Conditions
Boundary conditions are hard to keep track of. Put the processing for them in one
place.
if (level + 1 < tags.length) {
parts = new Parse(body, tags, level + 1, offset + endTag);
body = null;
}
int nextLevel = level + 1;
if (nextLevel < tags.length) {
parts = new Parse(body, tags, nextLevel, offset + endTag);
body = null;
}
General
• Constants versus Enums
Don’t keep using the old trick of public static final ints. Enums can
have methods and fields. This makes them very powerful tools that allow much
more expression and flexibility.
public enum HourlyPayGrade {
APPRENTICE {
public double rate() {
return 1.0;
}
},
MASTER {
public double rate() {
return 2.0;
}
};
public abstract double rate();
}
public class HourlyEmployee extends Employee {
private int tenthsWorked;
HourlyPayGrade grade;
public Money calculatePay() {
int straightTime = Math.min(tenthsWorked, TENTHS_PER_WEEK);
int overTime = tenthsWorked - straightTime;
return new Money(
grade.rate() * (tenthsWorked + OVERTIME_RATE * overTime)
);
}
/…
}
Clean Code

Contenu connexe

Tendances

Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionKent Huang
 
Naming Standards, Clean Code
Naming Standards, Clean CodeNaming Standards, Clean Code
Naming Standards, Clean CodeCleanestCode
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code PrinciplesYeurDreamin'
 
The Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable DesignThe Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable DesignVictor Rentea
 
The Clean Architecture
The Clean ArchitectureThe Clean Architecture
The Clean ArchitectureDmytro Turskyi
 
Clean Code - The Next Chapter
Clean Code - The Next ChapterClean Code - The Next Chapter
Clean Code - The Next ChapterVictor Rentea
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
Clean code - DSC DYPCOE
Clean code - DSC DYPCOEClean code - DSC DYPCOE
Clean code - DSC DYPCOEPatil Shreyas
 
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithVictor Rentea
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable codeGeshan Manandhar
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean ArchitectureMattia Battiston
 

Tendances (20)

Clean code
Clean codeClean code
Clean code
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Clean Code
Clean CodeClean Code
Clean Code
 
Naming Standards, Clean Code
Naming Standards, Clean CodeNaming Standards, Clean Code
Naming Standards, Clean Code
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
 
The Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable DesignThe Art of Unit Testing - Towards a Testable Design
The Art of Unit Testing - Towards a Testable Design
 
The Clean Architecture
The Clean ArchitectureThe Clean Architecture
The Clean Architecture
 
Clean Code - The Next Chapter
Clean Code - The Next ChapterClean Code - The Next Chapter
Clean Code - The Next Chapter
 
Clean Code
Clean CodeClean Code
Clean Code
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
Clean Code
Clean CodeClean Code
Clean Code
 
Clean code
Clean codeClean code
Clean code
 
Clean code - DSC DYPCOE
Clean code - DSC DYPCOEClean code - DSC DYPCOE
Clean code - DSC DYPCOE
 
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
 
Clean code
Clean code Clean code
Clean code
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 

Similaire à Clean Code

Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012cobyst
 
On Coding Guidelines
On Coding GuidelinesOn Coding Guidelines
On Coding GuidelinesDIlawar Singh
 
Principled And Clean Coding
Principled And Clean CodingPrincipled And Clean Coding
Principled And Clean CodingMetin Ogurlu
 
Introduction to Software Engineering with C++
Introduction to Software Engineering  with C++Introduction to Software Engineering  with C++
Introduction to Software Engineering with C++Mohamed Essam
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003R696
 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1Philip Schwarz
 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsPhilip Schwarz
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddSrinivasa GV
 
Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)Shirish Bari
 
Best Coding Practices in Java and C++
Best Coding Practices in Java and C++Best Coding Practices in Java and C++
Best Coding Practices in Java and C++Nitin Aggarwal
 
CLEAN CODING AND DEVOPS Final.pptx
CLEAN CODING AND DEVOPS Final.pptxCLEAN CODING AND DEVOPS Final.pptx
CLEAN CODING AND DEVOPS Final.pptxJEEVANANTHAMG6
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean codeVictor Rentea
 
Can't Dance The Lambda
Can't Dance The LambdaCan't Dance The Lambda
Can't Dance The LambdaTogakangaroo
 

Similaire à Clean Code (20)

Coding Standards
Coding StandardsCoding Standards
Coding Standards
 
Clean code
Clean codeClean code
Clean code
 
Clean code, Feb 2012
Clean code, Feb 2012Clean code, Feb 2012
Clean code, Feb 2012
 
On Coding Guidelines
On Coding GuidelinesOn Coding Guidelines
On Coding Guidelines
 
Clean code and code smells
Clean code and code smellsClean code and code smells
Clean code and code smells
 
Principled And Clean Coding
Principled And Clean CodingPrincipled And Clean Coding
Principled And Clean Coding
 
Introduction to Software Engineering with C++
Introduction to Software Engineering  with C++Introduction to Software Engineering  with C++
Introduction to Software Engineering with C++
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1The Sieve of Eratosthenes - Part 1
The Sieve of Eratosthenes - Part 1
 
The Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor correctionsThe Sieve of Eratosthenes - Part 1 - with minor corrections
The Sieve of Eratosthenes - Part 1 - with minor corrections
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 
Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)Writing Clean Code (Recommendations by Robert Martin)
Writing Clean Code (Recommendations by Robert Martin)
 
Best Coding Practices in Java and C++
Best Coding Practices in Java and C++Best Coding Practices in Java and C++
Best Coding Practices in Java and C++
 
Clean Code 2
Clean Code 2Clean Code 2
Clean Code 2
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
CLEAN CODING AND DEVOPS Final.pptx
CLEAN CODING AND DEVOPS Final.pptxCLEAN CODING AND DEVOPS Final.pptx
CLEAN CODING AND DEVOPS Final.pptx
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean code
 
C Programming - Refresher - Part IV
C Programming - Refresher - Part IVC Programming - Refresher - Part IV
C Programming - Refresher - Part IV
 
Can't Dance The Lambda
Can't Dance The LambdaCan't Dance The Lambda
Can't Dance The Lambda
 

Dernier

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 

Dernier (20)

Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 

Clean Code

  • 1. by Dmytro Turskyi (March 2023) (2008) By Robert C. Martin (aka “Uncle Bob”)
  • 2. Agenda • Meaningful Names • Functions • Comments • Error Handling • Classes • Environment • General
  • 3. Meaningful Names • Avoid Mental Mapping A single-letter name is a poor choice; it’s just a place holder that the reader must mentally map to the actual concept. There can be no worse reason for using the name “c” than because “a” and “b” were already taken. • Method names Methods should have verb or verb phrase names like postPayment, deletePage, or save. Accessors, mutators, and predicates should be named for their value and prefixed with get…, set…, and is…
  • 4. Meaningful Names • Use Searchable Names const int WORK_DAYS_PER_WEEK = 5; int realDaysPerIdealDay = 4; 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; } for (int j = 0; j < 34; j++) { s += (t [ j ] * 4) / 5; } 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
  • 5. Meaningful Names • Use Intention-Revealing Names If a name requires a comment, then the name does not reveal its intent. public List<int[]> getThem() { List<int[]> list1 = new ArrayList<>(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1; } public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<>(); for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell); return flaggedCells; }
  • 6. Meaningful Names • Use Pronounceable Names class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = "102"; } class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; } If you can’t pronounce it, you can’t discuss it without sounding like an idiot.
  • 7. Meaningful Names • Class Names Manager, Processor, Data, Info. or
  • 8. Meaningful Names • Class Names Customer, WikiPage, Account, AddressParser. Classes and objects should have noun or noun phrase names and not include indistinct noise words: Manager, Processor, Data, Info.
  • 9. Functions • Small! The first rule of functions is that they should be small. Functions should hardly ever be ??? lines long. Blocks within if statements, else statements, while statements, and so on should be ??? long.
  • 10. Functions • Small! The first rule of functions is that they should be small. Functions should hardly ever be 20 lines long. Blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. • Do One Thing To know that a function is doing more than “one thing” is if you can extract another function from it with a name that is not merely a restatement of its implementation.
  • 11. Functions • One Level of Abstraction per Function We want the code to read like a top-down narrative. 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. public String render() throws Exception { StringBuffer html = new StringBuffer(“<hr"); if(size > 0) html.append(" size="") .append(size + 1).append(“”"); html.append(">"); return html.toString(); } public String render() throws Exception { HtmlTag hr = new HtmlTag(“hr"); if (extraDashes > 0) hr.addAttribute(“size", hrSize(extraDashes)); return hr.html(); } private String hrSize(int height) { int hrSize = height + 1; return String.format("%d", hrSize); }
  • 12. Functions • Use Descriptive Names 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. • Dependent Functions. If one function calls another, they should be vertically close, and the caller should be above the callee, if at all possible.
  • 13. Functions • Function Arguments The ideal number of arguments for a function is ??? . includeSetupPageInto(newPageContent) or
  • 14. Functions • Function Arguments The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. includeSetupPage() includeSetupPageInto(newPageContent)
  • 15. Functions • Flag Arguments Flag arguments are ugly. Passing a boolean into a function is a truly terrible practice. It immediately complicates the signature of the method, loudly proclaiming that this function does more than one thing. It does one thing if the flag is true and another if the flag is false! render(boolean isSuite) renderForSuite() renderForSingleTest()
  • 16. Functions • Have No Side Effects public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } } return false; }
  • 17. Functions • Have No Side Effects Side effects are lies. public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } } return false; } checkPasswordAndInitializeSession
  • 18. Functions • Output Arguments For example: appendFooter(s); Does this function append “s” as the footer to something? Or does it append some footer to “s”? Is “s” an input or an output? It doesn’t take long to look at the function signature and see, but anything that forces you to check the function signature is equivalent to a double- take. It’s a cognitive break and should be avoided. public void appendFooter(StringBuffer report) report.appendFooter();
  • 19. Comments // Check to see if the employee is eligible // for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) or
  • 20. Comments • Explain Yourself in Code Only the code can truly tell you what it does. Comments are, at best, a necessary evil. Rather than spend your time writing the comments that explain the mess you’ve made, spend it cleaning that mess. Inaccurate comments are far worse than no comments at all. if (employee.isEligibleForFullBenefits()) // Check to see if the employee is eligible // for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
  • 21. Comments • Legal Comments Sometimes our corporate coding standards force us to write certain comments for legal reasons. // Copyright (C) 2003,2004,2005 by Object // Mentor, Inc. All rights reserved. // Released under the terms of the GNU // General Public License version 2 or later. • Explanation of Intent Sometimes a comment goes beyond just useful information about the implementation and provides the intent behind a decision. // This is our best attempt to get a race condition // by creating large number of threads. for (int i = 0; i < 25000; i++) { WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, text, parent, failFlag); Thread thread = new Thread(widgetBuilderThread); thread.start(); }
  • 22. Comments • Warning of Consequences Sometimes it is useful to warn other programmers about certain consequences. public static SimpleDateFormat makeStandardHttpDateFormat() { //SimpleDateFormat is not thread safe, //so we need to create each instance independently. SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); df.setTimeZone(TimeZone.getTimeZone("GMT")); return df; } • TODO Comments Nowadays, most good IDEs provide special gestures and features to locate all the //TODO comments, so it’s not likely that they will get lost. //TODO-MdM these are not needed // We expect this to go away when we do the // checkout model protected VersionInfo makeVersion() throws Exception{ return null; }
  • 23. Comments • Amplification A comment may be used to amplify the importance of something that may otherwise seem inconsequential. String listItemContent = match.group(3).trim(); // the trim is real important. It removes the starting // spaces that could cause the item to be recognised // as another list. new ListItemWidget(this, listItemContent, this.level + 1); return buildList(text.substring(match.end())); • Public APIs There is nothing quite so helpful and satisfying as a well- described public API. It would be difficult, at best, to write programs without them. /// dart doc comment /** * JavaDoc comment */
  • 24. Comments • Commented-Out Code We’ve had good source code control systems for a very long time now. Those systems will remember the code for us. We don’t have to comment it out any more. Just delete the code. • Position Markers In general they are clutter that should be eliminated— especially the noisy train of slashes at the end. If you overuse banners, they’ll fall into the background noise and be ignored. // Actions ////////////////////////////////// InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));
  • 25. Error Handling • Don’t Return Null When we return null, we are essentially creating work for ourselves and foisting problems upon our callers. All it takes is one missing null check to send an application spinning out of control. List<Employee> employees = getEmployees(); if (employees != null) { for (Employee e : employees) { totalPay += e.getPay(); } } public List<Employee> getEmployees() { if ( .. there are no employees .. ) return Collections.emptyList(); }
  • 26. Error Handling • Don’t Pass Null In most programming languages there is no way to deal with a null that is passed by a caller accidentally. Because this is the case, the rational approach is to forbid passing null by default. When you do, you can code with the knowledge that a null in an argument list is an indication of a problem, and end up with far fewer careless mistakes. calculator.xProjection(null, new Point(12, 13));
  • 27. Classes • Classes Should Be Small! With functions we measured size by counting physical lines. With classes we use a different measure. We count ???.
  • 28. Classes • Classes Should Be Small! With functions we measured size by counting physical lines. With classes we use a different measure. We count responsibilities. The Single Responsibility Principle (SRP) states that a class or module should have one, and only one, reason to change. The name of a class should describe what responsibilities it fulfills. The more ambiguous the class name, the more likely it has too many responsibilities. The problem is that too many of us think that we are done once the program works. We move on to the next problem rather than going back and breaking the overstuffed classes into decoupled units with single responsibilities.
  • 29. Classes public class SuperDashboard extends JFrame implements MetaDataUser public String getCustomizerLanguagePath() public void setSystemConfigPath(String systemConfigPath) public String getSystemConfigDocument() public void setSystemConfigDocument(String systemConfigDocument) public boolean getGuruState() public boolean getNoviceState() public boolean getOpenSourceState() public void showObject(MetaObject object) public void showProgress(String s) public void setACowDragging(boolean allowDragging) public boolean allowDragging() public boolean isCustomizing() public void setTitle(String title) public IdeMenuBar getIdeMenuBar() public void showHelper(MetaObject metaObject, String propertyName) // ... many non-public methods follow ... } public class Version { public int getMajorVersionNumber() public int getMinorVersionNumber() public int getBuildNumber() }
  • 30. Environment • Build Requires More Than One Step Building a project should be a single trivial operation. You should not have to check many little pieces out from source code control. You should be able to check out the system with one simple command and then issue one other simple command to build it. svn get mySystem cd mySystem ant all • Tests Require More Than One Step You should be able to run all the unit tests with just one command. In the best case you can run all the tests by clicking on one button in your IDE.
  • 31. General • Artificial Coupling In general an artificial coupling is a coupling between two modules that serves no direct purpose. It is a result of putting a variable, constant, or function in a temporarily convenient, though inappropriate, location. For example, general enumsshould not be contained within more specific classes because this forces the whole application to know about these more specific classes. The same goes for general purpose static functions being declared in specific classes. • Prefer Polymorphism to If/Else or Switch/Case There may be no more than one switch statement for a given type of selection. The cases in that switch statement must create polymorphic objects that take the place of other such switch statements in the rest of the system.
  • 32. General • Replace Magic Numbers with Named Constants In general it is a bad idea to have raw numbers in your code. You should hide them behind well-named constants. The term “Magic Number” does not apply only to numbers. It applies to any token that has a value that is not self-describing. assertEquals(7777, Employee.find(“John Doe”).employeeNumber()); assertEquals( HOURLY_EMPLOYEE_ID, Employee.find(HOURLY_EMPLOYEE_NAME).employeeNumber());
  • 33. General • Encapsulate Conditionals Boolean logic is hard enough to understand without having to see it in the context of an if or while statement. Extract functions that explain the intent of the conditional. if (shouldBeDeleted(timer)) if (timer.hasExpired() && !timer.isRecurrent()) • Avoid Negative Conditionals Negatives are just a bit harder to understand than positives. So, when possible, conditionals should be expressed as positives. if (buffer.shouldCompact()) if (!buffer.shouldNotCompact())
  • 34. General • Encapsulate Boundary Conditions Boundary conditions are hard to keep track of. Put the processing for them in one place. if (level + 1 < tags.length) { parts = new Parse(body, tags, level + 1, offset + endTag); body = null; } int nextLevel = level + 1; if (nextLevel < tags.length) { parts = new Parse(body, tags, nextLevel, offset + endTag); body = null; }
  • 35. General • Constants versus Enums Don’t keep using the old trick of public static final ints. Enums can have methods and fields. This makes them very powerful tools that allow much more expression and flexibility. public enum HourlyPayGrade { APPRENTICE { public double rate() { return 1.0; } }, MASTER { public double rate() { return 2.0; } }; public abstract double rate(); } public class HourlyEmployee extends Employee { private int tenthsWorked; HourlyPayGrade grade; public Money calculatePay() { int straightTime = Math.min(tenthsWorked, TENTHS_PER_WEEK); int overTime = tenthsWorked - straightTime; return new Money( grade.rate() * (tenthsWorked + OVERTIME_RATE * overTime) ); } /… }