SlideShare a Scribd company logo
Perfect Code! 
How to write high-quality code! 
ARTEM TABALIN!
Motivation! 
Why should we always improve our code?! 
Why code that just works is not enough? !
Code Quality Control Law ! 
Improving code quality reduces development costs! 
Why?! 
Developer average productivity is! 
10-50 lines per day! 
Writing code – 10%! 
Reading code, testing, debugging – 90%! 
!
Productivity vs Time! 
Productivity decreases with entropy increasing! 
Time 
Productivity
Software Development Paradox! 
1. Low-quality code slows down development! 
2. Devs reduce code quality to meet a deadline! 
Paradox: “Devs have no time to work rapidly”! 
The clue: #2 is wrong! 
Impossible to successfully meet a deadline messing up the code! 
Continuously maintain high code quality!
The Boy Scout Rule! 
It’s not enough to write code well - prevent “rotting”! 
! 
“Leave the campground cleaner than you found it”! 
!
Software Development Principles! 
KISS, YAGNI, DRY, SOLID!
Keep Code Simple! 
KISS (Keep It Simple, Stupid)! 
Simplicity is a key goal! 
Components should be integrated tightly or weakly (?)! 
Try to reduce influence between components! 
Follow “Divide and Conquer” principle! 
!
Division of Responsibilities! 
• System → packages! 
• Package → classes! 
• Class → methods! 
• Method → control statements! 
Low coupling on each level!
Use Patterns! 
Don’t reinvent the square wheel! 
• Reduce complexity! 
• Less mistakes! 
• Simplify communication! 
! 
Examples: Repository, Factory, Adapter, Strategy, Observer!
No Unnecessary Code! 
YAGNI (You Aren’t Gonna Need It)! 
Implement things only when you really need them! 
!
Avoid Duplication! 
DRY (Don’t Repeat Yourself)! 
! 
“Every piece of knowledge must have a single, unambiguous, 
authoritative representation within a system.”! 
!
Object-Oriented Design! 
SOLID! 
1. Single Responsibility (SRP)! 
2. Open-Closed (OCP)! 
3. Liskov Substitution (LSP)! 
4. Interface Segregation (ISP)! 
5. Dependency Inversion (DIP)!
Single Responsibility Principle! 
“A class should have one and only one reason to change”! 
!
Open-Closed Principle! 
Class should be opened to extension and closed for modification! 
GraphicEditor 
+drawShape 
Shape 
+draw 
Rectangle 
+draw 
Circle 
+draw 
violation 
+drawCircle 
+drawRectangle 
+drawTriangle 
Triangle 
+draw
Liskov Substitution Principle! 
Objects implementing an interface can be used interchangeably! 
! 
GraphicEditor 
+resize(IResizable) 
IResizable 
+bounds 
+resize 
Shape 
+bounds 
+resize 
Image 
+bounds 
+resize 
violation 
resize(IResizable obj) { 
if(obj is TextBlock) 
return; 
obj.resize(); 
} 
TextBlock 
+bounds 
+resize
Interface Segregation Principle! 
Clients should not depend on interfaces they don’t use! 
! 
Shape 
+resize 
+move 
+select 
IResizable 
+resize 
violation 
IGraphic 
+resize 
+move 
+select 
ISelectable 
+select 
IMovable 
+move
Dependency Inversion Principle! 
Abstractions should not depend on details! 
GraphicEditor 
+logger: ILogger 
ILogger 
violation 
GraphicEditor() { 
logger = new FileLogger(); 
} 
EmailLogger FileLogger 
SystemLogger
Meaningful Names! 
Naming principles. Name length. Variable names. ! 
Class names. Method names.!
Naming Principles! 
Name should show your intention! 
int 
d; 
// 
elapsed 
time 
Is it good enough?! 
Which name is better?! 
int 
elapsedTimeInDays; 
int 
daysSinceCreation; 
! 
!
Naming Principles! 
What does the following code do?! 
function 
getItems(items) 
{ 
var 
list1 
= 
[]; 
for(var 
i 
= 
0; 
i 
< 
items.length; 
i++) 
{ 
var 
x 
= 
items[i]; 
if(items[i]["Field"] 
=== 
12) 
{ 
list1.push(x); 
} 
} 
return 
list1; 
} 
!
Naming Principles! 
What is about this one?! 
function 
getMarkedCells(cells) 
{ 
var 
result 
= 
[]; 
for(var 
i 
= 
0; 
i 
< 
cells.length; 
i++) 
{ 
var 
cell 
= 
cells[i]; 
if(cell.Status 
=== 
CellStatus.Marked) 
{ 
result.push(cell); 
} 
} 
return 
result; 
}
Naming Principles! 
No implementation details! 
HashSet<Account> 
accountHashSet; 
Is it good enough? Why?! 
What if we decide to use List?! 
Which name is better?! 
HashSet<Account> 
accounts; 
!
Naming Principles! 
Choose easy-to-pronounce name! 
class 
Cstmr 
{ 
private 
int 
prsnid; 
private 
DateTime 
genTstmp; 
private 
DateTime 
modTstmp; 
} 
class 
Customer 
{ 
private 
int 
personId; 
private 
DateTime 
generationTimestamp; 
private 
DateTime 
modificationTimestamp; 
} 
!
Naming Principles! 
• Single word for concept (avoid synonyms)! 
fetch / retrieve / get controller / manager / driver! 
• Names from patterns and algos! 
RenderStrategy, JobQueue! 
• Names from user stories! 
Credit, Debit, Asset! 
• Antonyms! 
begin / end first / last min / max next / previous! 
old / new opened / closed source / target up / down! 
!
Naming Convention! 
The most important is to follow to the convention! 
Example:! 
• CONSTANT 
• ClassName 
• localVariable 
• _privateMember
Name Length! 
What is the optimal length for a name?! 
x → maximumNumberOfPointsInEachLine 
short / long name pros & cons! 
short names – lacks of information! 
long names – harder to read and write! 
! 
10-16 characters is the optimal length! 
if < 10 ask: is meaningful enough?! 
if > 16 ask: isn’t verbose?!
Loop Variable Names! 
• Simple loop! 
for(int 
i 
= 
0; 
i 
< 
data.length; 
i++) 
{ 
data[i] 
= 
0; 
} 
• Complex loop! 
for(int 
teamIndex 
= 
0; 
teamIndex 
< 
teamCount; 
teamIndex++) 
{ 
for(int 
playerIndex 
= 
0; 
playerIndex 
< 
count; 
playerIndex++) 
{ 
playerStore[teamIndex][playerIndex] 
= 
0; 
} 
}!
Loop Variable Names! 
• Variable used outside of the loop 
int 
recordCount 
= 
0; 
while(moreRecords()) 
{ 
data[recordCount] 
= 
getNextRecord(); 
recordCount++; 
} 
// 
… 
recordCount 
is 
accessed 
here 
!
Temporary Variable Names! 
Avoid pointless names! 
temp 
= 
sqrt(b^2 
-­‐ 
4*a*c); 
root[0] 
= 
(-­‐b 
+ 
temp) 
/ 
(2*a); 
root[1] 
= 
(-­‐b 
-­‐ 
temp) 
/ 
(2*a); 
How to improve?! 
discriminant 
= 
sqrt(b^2 
-­‐ 
4*a*c); 
root[0] 
= 
(-­‐b 
+ 
discriminant) 
/ 
(2*a); 
root[1] 
= 
(-­‐b 
-­‐ 
discriminant) 
/ 
(2*a); 
!
Boolean Variables and Methods! 
Use verbs is, has, can for booleans! 
• isSupported! 
• hasNext! 
• canExecute!
Class Names! 
Use nouns and noun combinations for classes! 
• Client! 
• Window! 
• UserAccount! 
• FileLoader!
Method Names! 
Use verbs and verb phrases for methods! 
• Save! 
• Close! 
• GetAccount! 
• LoadFile!
Variables! 
Declaration. Initialization. Lifetime and scope.!
Declaration! 
• Declare all variables! 
• Turn off implicit variable declaration! 
JavaScript: 
“use 
strict” 
VB: 
Option 
Explicit 
On 
php: 
error_reporting(E_STRICT); 
!
Initialization! 
Initialize variables at declaration! 
var 
total 
= 
0; 
or at first occurrence in code! 
Dim 
total 
As 
Double 
' 
another 
code 
total 
= 
0.0 
' 
code 
using 
total 
!
Lifetime and Scope! 
Variables lifetime and scope should be minimal! 
Why?! 
Does code follow the principle?! 
function 
summarizeData() 
{ 
var 
oldData 
= 
getOldData(); 
var 
totalOldData 
= 
summarize(oldData); 
printData(totalOldData); 
saveData(totalOldData); 
var 
newData 
= 
getNewData(); 
var 
totalNewData 
= 
summarize(newData); 
printData(totalNewData); 
saveData(totalNewData); 
}
Lifetime and Scope! 
Code might look like! 
function 
summarizeData() 
{ 
var 
oldData 
= 
getOldData(); 
var 
newData 
= 
getNewData(); 
var 
totalOldData 
= 
summarize(oldData); 
var 
totalNewData 
= 
summarize(newData); 
printData(totalOldData); 
printData(totalNewData); 
saveData(totalOldData); 
saveData(totalNewData); 
} 
! 
!
Lifetime and Scope! 
• Single purpose principle! 
int 
value 
= 
getValue(); 
int 
result 
= 
calcResult(value); 
// 
some 
code 
value 
= 
val1; 
val1 
= 
val2; 
val2 
= 
value; 
• Avoid global variables! 
• Prefer the most restrictive access level! 
private → public! 
var 
swap 
= 
val1; 
val1 
= 
val2; 
val2 
= 
swap; 
→
Methods (Functions)! 
Purposes. Principles. Order. Parameters.!
Purposes! 
• Simplify code! 
• Improve readability! 
• Documentation defines abstraction! 
• Eliminating duplication most popular! 
• Inheritance support method overriding!
Principles! 
Method should be small! 
How many lines?! 
not more than 20 lines and better even less! 
Example:! 
public 
ReportContainer 
BuildReport(IList<Order> 
orders) 
{ 
var 
report 
= 
new 
ReportContainer(); 
report.Lines 
= 
BuildReportLines(orders); 
report.Total 
= 
BuildReportTotal(report.Lines); 
return 
report; 
} 
!
Principles! 
Method should have! 
• blocks (if, else, for, while) 1-3 lines long! 
• indent level not more than 2! 
private 
IList<ReportLine> 
BuildReportLines(IList<Order> 
orders) 
{ 
IList<ReportLine> 
result 
= 
new 
List<ReportLine>(); 
foreach 
(Order 
order 
in 
orders) 
{ 
ReportLine 
reportLine 
= 
BuildReportLine(order); 
if 
(reportLine.IsVisible) 
result.Add(reportLine); 
} 
return 
result; 
} 
!
Principles! 
Single Thing Rule! 
Function should do one thing, do it only, and do it well! 
Examples:! 
• BuildReport – makes report! 
• BuildReportLines – prepares report lines! 
• BuildReportTotal – summarizes report! 
Criteria: function cannot be divided into sections!
Principles! 
Single Abstraction Level! 
Mixing up abstraction levels increases complexity! 
Does code follow the principle? Why?! 
private 
Report 
BuildReport(Order 
order) 
{ 
var 
result 
= 
new 
Report(); 
result.Header 
= 
BuildReportHeader(order.Title); 
result.Body 
= 
ReportHelper.TextToHtml(order.Description); 
result.Footer 
= 
"<b>" 
+ 
APP_NAME 
+ 
"</b>"; 
result.Footer 
+= 
" 
CopyRight 
© 
" 
+ 
DateTime.Now.Year; 
return 
result; 
} 
!
Principles! 
Better! 
private 
Report 
BuildReport(Order 
order) 
{ 
var 
result 
= 
new 
Report(); 
result.Header 
= 
BuildReportHeader(order.Title); 
result.Body 
= 
ReportHelper.TextToHtml(order.Description); 
result.Footer 
= 
BuildReportFooter(); 
return 
result; 
} 
Much Better! 
private 
Report 
BuildReport(Order 
order) 
{ 
var 
result 
= 
new 
Report(); 
result.Header 
= 
BuildReportHeader(order.Title); 
result.Body 
= 
BuildReportBody(order.Description); 
result.Footer 
= 
BuildReportFooter(); 
return 
result; 
} 
!
Principles! 
Command-Query Separation (CQS)! 
Method performs an action OR returns data! 
Does code follow the principle?! 
if 
(SetAttribute("username", 
"Admin")) 
{ 
// 
code 
} 
How to fix? 
if 
(HasAttribute("username")) 
{ 
SetAttribute("username", 
"Admin"); 
// 
code 
}
Order! 
The Stepdown Rule! 
Read code from top to bottom (by abstraction levels)! 
public 
Report 
BuildReport(IList<Order> 
orders) 
{ 
// 
uses 
BuildReportLines 
and 
BuildReportTotal 
} 
private 
Report 
BuildReportLines(IList<Order> 
orders) 
{ 
// 
uses 
BuildReportLine 
} 
private 
Report 
BuildReportLine(IList<Order> 
orders) 
{ 
// 
code 
} 
private 
Report 
BuildReportTotal(IList<Order> 
orders) 
{ 
// 
code 
}
Arguments! 
How many parameters should a method have?! 
• Ideally 0! 
• Avoid methods with more than 2 arguments! 
Why?! 
• Harder to read (remember passing values)! 
• Increase coupling! 
• Harder to test (combinatorial growth of variants)!
Arguments! 
Avoid boolean arguments! 
Why?! 
• Usually can be divided into two sections! 
• Hard to understand a purpose of an argument! 
BuildReportLine(order, 
true); 
private 
Report 
BuildReportLine(Order 
order, 
bool 
isMarked) 
{ 
if 
(isMarked) 
{ 
// 
build 
marked 
report 
line 
} 
else 
{ 
// 
build 
simple 
report 
line 
} 
}
Classes! 
Purposes. Principles. Interface. Encapsulation. 
Inheritance.!
Purposes! 
• Simplify code 
• Improve readability! 
• Limit the scope of changes! 
• Hide implementation details (encapsulation)! 
• Allow to prepare generic solution (abstraction)! 
• Eliminate duplication (delegation & inheritance)! 
• Provide extensibility (inheritance)! 
• Allow to work with real domain entities!
Principles! 
• Encapsulation! 
Hide as much as possible! 
• Compactness! 
Reduce class responsibilities (SRP)! 
• Abstraction! 
Program to an interface, not an implementation! 
• High Cohesion! 
Fields and methods should belong together!
Interface! 
Methods should be on the same abstraction level! 
Does code follow the principle? Why?! 
class 
Program 
{ 
public 
void 
InitializeCommandStack(); 
public 
void 
PushCommand(Command 
command); 
public 
Command 
PopCommand(); 
public 
void 
ShutdownCommandStack(); 
public 
void 
InitializeReportFormatting(); 
public 
void 
FormatReport(Report 
report); 
public 
void 
PrintReport(Report 
report); 
public 
void 
InitializeGlobalData(); 
public 
void 
ShutdownGlobalData(); 
}
Interface! 
Programming over semantic! 
• Programming – can be checked by compiler! 
Amount of arguments! 
Argument types! 
• Semantic – cannot be checked by compiler! 
Method A should be called after method B! 
Method A throws exception when argument is not initialized! 
!
Encapsulation! 
• Not public should be private ! 
private → public! 
• No direct access to fields! 
private 
decimal 
_x 
= 
0; 
public 
decimal 
X 
{ 
get 
{ 
return 
_x; 
} 
set 
{ 
_x 
= 
value; 
} 
} 
• No assumptions about class clients! 
// 
param2 
should 
be 
> 
0, 
in 
other 
case 
method 
fails 
public 
int 
Method(int 
param1, 
int 
param2) 
!
Inheritance! 
Should be able to say that child ‘is’ parent! 
Circle is Shape HtmlParser is Parser! 
Does code follow the principle?! 
class 
Customer 
{ 
public 
int 
ID 
{ 
get; 
set; 
} 
public 
string 
Name 
{ 
get; 
set; 
} 
} 
class 
Bank: 
Customer 
{ 
public 
string 
CorrespondentAccount 
{ 
get; 
set; 
} 
} 
Depends on whether a bank can be a customer or not! 
!
Inheritance! 
Move common methods to base class! 
abstract 
class 
Stream 
{ 
public 
void 
Write(byte[] 
bytes); 
public 
byte[] 
Read(); 
} 
class 
SecureStream: 
Stream 
{ 
public 
void 
Init(StreamConfig 
config); 
} 
!
Inheritance! 
Avoid following situations:! 
• Parent class has only one child! 
• Child overrides method leaving it empty! 
• Too many hierarchy levels! 
better not more than 3 levels!
Comments! 
Commenting principles. Bad comments. Good 
comments.!
Commenting Principles! 
• Comments do not redress bad code! 
clean code much better than bad code with comments! 
• Do not comment tricky code – rewrite it! 
tricky code = bad code! 
• Try to explain with code! 
// 
is 
employee 
eligible 
for 
bonus 
if 
((employee.Schedule 
== 
HOURLY_SCHEDULE) 
&& 
employee.Age 
> 
65) 
{ 
… 
} 
! 
Better! 
if 
(employee.IsEligibleForBonus()) 
{ 
… 
}
Commenting Principles! 
Comment says “why” not “how”! 
• How! 
// 
if 
flag 
equals 
to 
zero 
if 
(accountFlag 
== 
0) 
• Why! 
// 
if 
new 
account 
created 
if 
(accountFlag 
== 
0) 
• Code instead of comment! 
if 
(accountType 
== 
AccountType.NewAccount)
Bad Comments! 
• Redundant comments! 
obvious and repeating code! 
// 
closing 
connection 
Connection.Close(); 
• Commented code! 
remove unnecessary code, VCS is for the rescue 
InputStream 
response 
= 
new 
InputStream(); 
response.SetBody(formatter.ResultStream, 
formatter.BytesCount); 
//InputStream 
resultStream 
= 
formatter.ResultStream; 
//StreamReader 
reader 
= 
new 
StreamReader(resultStream); 
//response.SetContent(reader.Read(formatter.BytesCount));
Good Comments! 
• Legal comments! 
license, copyright, author! 
• Explanations! 
provide info about inevitable tricks 
// 
NOTE: 
postpone 
execution 
to 
refresh 
UI 
setTimeout(function() 
{ 
// 
code 
}); 
• TODOs! 
notes for future to avoid “broken windows” 
// 
TODO: 
get 
rid 
of 
tricky 
workaround 
function 
badFunction() 
{ 
// 
tricky 
workaround 
here 
});
Thank you!! 
Your questions, please!! 
ARTEM TABALIN!
References! 
• Steve McConnell Code Complete! 
• Robert C. Martin Clean Code! 
• Hunt A., Thomas D. The Pragmatic Programmer ! 
• Craig Larman Applying UML and Patterns! 
• Kent Beck Implementation Patterns! 
• Eric Evans Domain-Driven Design!

More Related Content

PDF
Perfect Styling - How to write better CSS
PDF
Software Patterns
PDF
From Stairway to Heaven onto the Highway to Hell with Xtext
ZIP
URUG Ruby on Rails Workshop - Sesssion 5
KEY
Xtext Best Practices
PPTX
Cucumber_Training_ForQA
PDF
Cucumber in Practice(en)
PPTX
WordPress Coding Standards & WP Hooks
Perfect Styling - How to write better CSS
Software Patterns
From Stairway to Heaven onto the Highway to Hell with Xtext
URUG Ruby on Rails Workshop - Sesssion 5
Xtext Best Practices
Cucumber_Training_ForQA
Cucumber in Practice(en)
WordPress Coding Standards & WP Hooks

What's hot (20)

PDF
What is-sass-by-lucas-castro
PPTX
10 Ways To Abuse T-SQL
KEY
Testing gone-right
KEY
Why are preprocessors divisive
PDF
Scala Bay Meetup - The state of Scala code style and quality
PPTX
Active Record PowerPoint
PPT
Know Before it Goes: Testing Your Email Design
PPTX
Productive development with react js
PDF
Funtional Ruby - Mikhail Bortnyk
PDF
Vimperl
PPTX
International SEO
PDF
5 hs mpostcustomizationrenefonseca
PDF
Graduates Gone Mad: Innovations in Software
PDF
Five Enterprise Development Best Practices That EVERY Salesforce Org Can Use
PPTX
Spsbe using js-linkanddisplaytemplates
PDF
C++ 11 Style : A Touch of Class
PPTX
Functional programming
PPTX
Up to speed in domain driven design
PPTX
06 integrating extra features and looking forward
PPTX
How To Write Beautiful Code
What is-sass-by-lucas-castro
10 Ways To Abuse T-SQL
Testing gone-right
Why are preprocessors divisive
Scala Bay Meetup - The state of Scala code style and quality
Active Record PowerPoint
Know Before it Goes: Testing Your Email Design
Productive development with react js
Funtional Ruby - Mikhail Bortnyk
Vimperl
International SEO
5 hs mpostcustomizationrenefonseca
Graduates Gone Mad: Innovations in Software
Five Enterprise Development Best Practices That EVERY Salesforce Org Can Use
Spsbe using js-linkanddisplaytemplates
C++ 11 Style : A Touch of Class
Functional programming
Up to speed in domain driven design
06 integrating extra features and looking forward
How To Write Beautiful Code
Ad

Viewers also liked (20)

PDF
Refactoring
PDF
eXtreme Programming
PPTX
SOLID, DRY, SLAP design principles
PPT
SOLID Design Principles
PPTX
A Software Architect's View On Diagramming
PDF
The principles of good programming
PDF
Offline Web Apps
PPTX
Agile Agile: Adapting Practices to Support Explosive Growth by Ben Foster
PPTX
Interview: a Learning Conversation
PPTX
Lets talk About Good Code (Dallas TechFest 2014)
PDF
Smacss e-css-faz-bem
PDF
Guide to Human Activity System (HAS) Mapping
PDF
Ewan developing the agile mindset for organizational agility
PPTX
вольфсон построение собственного Agile-фреймворка (шаблон)
PPTX
Clean Code I - Design Patterns and Best Practices at SoCal Code Camp San Dieg...
PDF
Nguyen Vu Hung: Beyond Agile - Practices and Mindset - Agile Tour Vietnam (Ha...
PPT
Design Smells
PPT
Software Programming Principles
PPTX
GRASP Principles
PPT
The Smells Of Bad Design
Refactoring
eXtreme Programming
SOLID, DRY, SLAP design principles
SOLID Design Principles
A Software Architect's View On Diagramming
The principles of good programming
Offline Web Apps
Agile Agile: Adapting Practices to Support Explosive Growth by Ben Foster
Interview: a Learning Conversation
Lets talk About Good Code (Dallas TechFest 2014)
Smacss e-css-faz-bem
Guide to Human Activity System (HAS) Mapping
Ewan developing the agile mindset for organizational agility
вольфсон построение собственного Agile-фреймворка (шаблон)
Clean Code I - Design Patterns and Best Practices at SoCal Code Camp San Dieg...
Nguyen Vu Hung: Beyond Agile - Practices and Mindset - Agile Tour Vietnam (Ha...
Design Smells
Software Programming Principles
GRASP Principles
The Smells Of Bad Design
Ad

Similar to Perfect Code (20)

PPTX
Clean Code - Writing code for human
PDF
Guidelines to clean coding
PPTX
Writing High Quality Code in C#
PDF
What's in a name
PPTX
Variables
PDF
Clean Code
PPT
Clean Code summary
PPTX
Programming style guildelines
PPT
c-coding-standards-and-best-programming-practices.ppt
PDF
Clean code and code smells
PPTX
C# coding standards, good programming principles & refactoring
PPT
Clean code
PPT
Coding standard
PDF
PDF
Clean Code .Net Cheetsheets
PDF
76829060 java-coding-conventions
PPT
Coding Standards & Best Practices for iOS/C#
PPS
Coding Best Practices
PDF
Clean code
PDF
Seven Ineffective Coding Habits of Many Programmers
Clean Code - Writing code for human
Guidelines to clean coding
Writing High Quality Code in C#
What's in a name
Variables
Clean Code
Clean Code summary
Programming style guildelines
c-coding-standards-and-best-programming-practices.ppt
Clean code and code smells
C# coding standards, good programming principles & refactoring
Clean code
Coding standard
Clean Code .Net Cheetsheets
76829060 java-coding-conventions
Coding Standards & Best Practices for iOS/C#
Coding Best Practices
Clean code
Seven Ineffective Coding Habits of Many Programmers

Recently uploaded (20)

PDF
iTop VPN Crack Latest Version Full Key 2025
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PDF
Time Tracking Features That Teams and Organizations Actually Need
PDF
Wondershare Recoverit Full Crack New Version (Latest 2025)
PPTX
GSA Content Generator Crack (2025 Latest)
PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
Salesforce Agentforce AI Implementation.pdf
PPTX
Trending Python Topics for Data Visualization in 2025
PPTX
Patient Appointment Booking in Odoo with online payment
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PDF
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
chapter 5 systemdesign2008.pptx for cimputer science students
PDF
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PDF
MCP Security Tutorial - Beginner to Advanced
iTop VPN Crack Latest Version Full Key 2025
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
Time Tracking Features That Teams and Organizations Actually Need
Wondershare Recoverit Full Crack New Version (Latest 2025)
GSA Content Generator Crack (2025 Latest)
Computer Software and OS of computer science of grade 11.pptx
Salesforce Agentforce AI Implementation.pdf
Trending Python Topics for Data Visualization in 2025
Patient Appointment Booking in Odoo with online payment
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Designing Intelligence for the Shop Floor.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
Advanced SystemCare Ultimate Crack + Portable (2025)
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
Digital Systems & Binary Numbers (comprehensive )
chapter 5 systemdesign2008.pptx for cimputer science students
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
MCP Security Tutorial - Beginner to Advanced

Perfect Code

  • 1. Perfect Code! How to write high-quality code! ARTEM TABALIN!
  • 2. Motivation! Why should we always improve our code?! Why code that just works is not enough? !
  • 3. Code Quality Control Law ! Improving code quality reduces development costs! Why?! Developer average productivity is! 10-50 lines per day! Writing code – 10%! Reading code, testing, debugging – 90%! !
  • 4. Productivity vs Time! Productivity decreases with entropy increasing! Time Productivity
  • 5. Software Development Paradox! 1. Low-quality code slows down development! 2. Devs reduce code quality to meet a deadline! Paradox: “Devs have no time to work rapidly”! The clue: #2 is wrong! Impossible to successfully meet a deadline messing up the code! Continuously maintain high code quality!
  • 6. The Boy Scout Rule! It’s not enough to write code well - prevent “rotting”! ! “Leave the campground cleaner than you found it”! !
  • 7. Software Development Principles! KISS, YAGNI, DRY, SOLID!
  • 8. Keep Code Simple! KISS (Keep It Simple, Stupid)! Simplicity is a key goal! Components should be integrated tightly or weakly (?)! Try to reduce influence between components! Follow “Divide and Conquer” principle! !
  • 9. Division of Responsibilities! • System → packages! • Package → classes! • Class → methods! • Method → control statements! Low coupling on each level!
  • 10. Use Patterns! Don’t reinvent the square wheel! • Reduce complexity! • Less mistakes! • Simplify communication! ! Examples: Repository, Factory, Adapter, Strategy, Observer!
  • 11. No Unnecessary Code! YAGNI (You Aren’t Gonna Need It)! Implement things only when you really need them! !
  • 12. Avoid Duplication! DRY (Don’t Repeat Yourself)! ! “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”! !
  • 13. Object-Oriented Design! SOLID! 1. Single Responsibility (SRP)! 2. Open-Closed (OCP)! 3. Liskov Substitution (LSP)! 4. Interface Segregation (ISP)! 5. Dependency Inversion (DIP)!
  • 14. Single Responsibility Principle! “A class should have one and only one reason to change”! !
  • 15. Open-Closed Principle! Class should be opened to extension and closed for modification! GraphicEditor +drawShape Shape +draw Rectangle +draw Circle +draw violation +drawCircle +drawRectangle +drawTriangle Triangle +draw
  • 16. Liskov Substitution Principle! Objects implementing an interface can be used interchangeably! ! GraphicEditor +resize(IResizable) IResizable +bounds +resize Shape +bounds +resize Image +bounds +resize violation resize(IResizable obj) { if(obj is TextBlock) return; obj.resize(); } TextBlock +bounds +resize
  • 17. Interface Segregation Principle! Clients should not depend on interfaces they don’t use! ! Shape +resize +move +select IResizable +resize violation IGraphic +resize +move +select ISelectable +select IMovable +move
  • 18. Dependency Inversion Principle! Abstractions should not depend on details! GraphicEditor +logger: ILogger ILogger violation GraphicEditor() { logger = new FileLogger(); } EmailLogger FileLogger SystemLogger
  • 19. Meaningful Names! Naming principles. Name length. Variable names. ! Class names. Method names.!
  • 20. Naming Principles! Name should show your intention! int d; // elapsed time Is it good enough?! Which name is better?! int elapsedTimeInDays; int daysSinceCreation; ! !
  • 21. Naming Principles! What does the following code do?! function getItems(items) { var list1 = []; for(var i = 0; i < items.length; i++) { var x = items[i]; if(items[i]["Field"] === 12) { list1.push(x); } } return list1; } !
  • 22. Naming Principles! What is about this one?! function getMarkedCells(cells) { var result = []; for(var i = 0; i < cells.length; i++) { var cell = cells[i]; if(cell.Status === CellStatus.Marked) { result.push(cell); } } return result; }
  • 23. Naming Principles! No implementation details! HashSet<Account> accountHashSet; Is it good enough? Why?! What if we decide to use List?! Which name is better?! HashSet<Account> accounts; !
  • 24. Naming Principles! Choose easy-to-pronounce name! class Cstmr { private int prsnid; private DateTime genTstmp; private DateTime modTstmp; } class Customer { private int personId; private DateTime generationTimestamp; private DateTime modificationTimestamp; } !
  • 25. Naming Principles! • Single word for concept (avoid synonyms)! fetch / retrieve / get controller / manager / driver! • Names from patterns and algos! RenderStrategy, JobQueue! • Names from user stories! Credit, Debit, Asset! • Antonyms! begin / end first / last min / max next / previous! old / new opened / closed source / target up / down! !
  • 26. Naming Convention! The most important is to follow to the convention! Example:! • CONSTANT • ClassName • localVariable • _privateMember
  • 27. Name Length! What is the optimal length for a name?! x → maximumNumberOfPointsInEachLine short / long name pros & cons! short names – lacks of information! long names – harder to read and write! ! 10-16 characters is the optimal length! if < 10 ask: is meaningful enough?! if > 16 ask: isn’t verbose?!
  • 28. Loop Variable Names! • Simple loop! for(int i = 0; i < data.length; i++) { data[i] = 0; } • Complex loop! for(int teamIndex = 0; teamIndex < teamCount; teamIndex++) { for(int playerIndex = 0; playerIndex < count; playerIndex++) { playerStore[teamIndex][playerIndex] = 0; } }!
  • 29. Loop Variable Names! • Variable used outside of the loop int recordCount = 0; while(moreRecords()) { data[recordCount] = getNextRecord(); recordCount++; } // … recordCount is accessed here !
  • 30. Temporary Variable Names! Avoid pointless names! temp = sqrt(b^2 -­‐ 4*a*c); root[0] = (-­‐b + temp) / (2*a); root[1] = (-­‐b -­‐ temp) / (2*a); How to improve?! discriminant = sqrt(b^2 -­‐ 4*a*c); root[0] = (-­‐b + discriminant) / (2*a); root[1] = (-­‐b -­‐ discriminant) / (2*a); !
  • 31. Boolean Variables and Methods! Use verbs is, has, can for booleans! • isSupported! • hasNext! • canExecute!
  • 32. Class Names! Use nouns and noun combinations for classes! • Client! • Window! • UserAccount! • FileLoader!
  • 33. Method Names! Use verbs and verb phrases for methods! • Save! • Close! • GetAccount! • LoadFile!
  • 35. Declaration! • Declare all variables! • Turn off implicit variable declaration! JavaScript: “use strict” VB: Option Explicit On php: error_reporting(E_STRICT); !
  • 36. Initialization! Initialize variables at declaration! var total = 0; or at first occurrence in code! Dim total As Double ' another code total = 0.0 ' code using total !
  • 37. Lifetime and Scope! Variables lifetime and scope should be minimal! Why?! Does code follow the principle?! function summarizeData() { var oldData = getOldData(); var totalOldData = summarize(oldData); printData(totalOldData); saveData(totalOldData); var newData = getNewData(); var totalNewData = summarize(newData); printData(totalNewData); saveData(totalNewData); }
  • 38. Lifetime and Scope! Code might look like! function summarizeData() { var oldData = getOldData(); var newData = getNewData(); var totalOldData = summarize(oldData); var totalNewData = summarize(newData); printData(totalOldData); printData(totalNewData); saveData(totalOldData); saveData(totalNewData); } ! !
  • 39. Lifetime and Scope! • Single purpose principle! int value = getValue(); int result = calcResult(value); // some code value = val1; val1 = val2; val2 = value; • Avoid global variables! • Prefer the most restrictive access level! private → public! var swap = val1; val1 = val2; val2 = swap; →
  • 40. Methods (Functions)! Purposes. Principles. Order. Parameters.!
  • 41. Purposes! • Simplify code! • Improve readability! • Documentation defines abstraction! • Eliminating duplication most popular! • Inheritance support method overriding!
  • 42. Principles! Method should be small! How many lines?! not more than 20 lines and better even less! Example:! public ReportContainer BuildReport(IList<Order> orders) { var report = new ReportContainer(); report.Lines = BuildReportLines(orders); report.Total = BuildReportTotal(report.Lines); return report; } !
  • 43. Principles! Method should have! • blocks (if, else, for, while) 1-3 lines long! • indent level not more than 2! private IList<ReportLine> BuildReportLines(IList<Order> orders) { IList<ReportLine> result = new List<ReportLine>(); foreach (Order order in orders) { ReportLine reportLine = BuildReportLine(order); if (reportLine.IsVisible) result.Add(reportLine); } return result; } !
  • 44. Principles! Single Thing Rule! Function should do one thing, do it only, and do it well! Examples:! • BuildReport – makes report! • BuildReportLines – prepares report lines! • BuildReportTotal – summarizes report! Criteria: function cannot be divided into sections!
  • 45. Principles! Single Abstraction Level! Mixing up abstraction levels increases complexity! Does code follow the principle? Why?! private Report BuildReport(Order order) { var result = new Report(); result.Header = BuildReportHeader(order.Title); result.Body = ReportHelper.TextToHtml(order.Description); result.Footer = "<b>" + APP_NAME + "</b>"; result.Footer += " CopyRight © " + DateTime.Now.Year; return result; } !
  • 46. Principles! Better! private Report BuildReport(Order order) { var result = new Report(); result.Header = BuildReportHeader(order.Title); result.Body = ReportHelper.TextToHtml(order.Description); result.Footer = BuildReportFooter(); return result; } Much Better! private Report BuildReport(Order order) { var result = new Report(); result.Header = BuildReportHeader(order.Title); result.Body = BuildReportBody(order.Description); result.Footer = BuildReportFooter(); return result; } !
  • 47. Principles! Command-Query Separation (CQS)! Method performs an action OR returns data! Does code follow the principle?! if (SetAttribute("username", "Admin")) { // code } How to fix? if (HasAttribute("username")) { SetAttribute("username", "Admin"); // code }
  • 48. Order! The Stepdown Rule! Read code from top to bottom (by abstraction levels)! public Report BuildReport(IList<Order> orders) { // uses BuildReportLines and BuildReportTotal } private Report BuildReportLines(IList<Order> orders) { // uses BuildReportLine } private Report BuildReportLine(IList<Order> orders) { // code } private Report BuildReportTotal(IList<Order> orders) { // code }
  • 49. Arguments! How many parameters should a method have?! • Ideally 0! • Avoid methods with more than 2 arguments! Why?! • Harder to read (remember passing values)! • Increase coupling! • Harder to test (combinatorial growth of variants)!
  • 50. Arguments! Avoid boolean arguments! Why?! • Usually can be divided into two sections! • Hard to understand a purpose of an argument! BuildReportLine(order, true); private Report BuildReportLine(Order order, bool isMarked) { if (isMarked) { // build marked report line } else { // build simple report line } }
  • 51. Classes! Purposes. Principles. Interface. Encapsulation. Inheritance.!
  • 52. Purposes! • Simplify code • Improve readability! • Limit the scope of changes! • Hide implementation details (encapsulation)! • Allow to prepare generic solution (abstraction)! • Eliminate duplication (delegation & inheritance)! • Provide extensibility (inheritance)! • Allow to work with real domain entities!
  • 53. Principles! • Encapsulation! Hide as much as possible! • Compactness! Reduce class responsibilities (SRP)! • Abstraction! Program to an interface, not an implementation! • High Cohesion! Fields and methods should belong together!
  • 54. Interface! Methods should be on the same abstraction level! Does code follow the principle? Why?! class Program { public void InitializeCommandStack(); public void PushCommand(Command command); public Command PopCommand(); public void ShutdownCommandStack(); public void InitializeReportFormatting(); public void FormatReport(Report report); public void PrintReport(Report report); public void InitializeGlobalData(); public void ShutdownGlobalData(); }
  • 55. Interface! Programming over semantic! • Programming – can be checked by compiler! Amount of arguments! Argument types! • Semantic – cannot be checked by compiler! Method A should be called after method B! Method A throws exception when argument is not initialized! !
  • 56. Encapsulation! • Not public should be private ! private → public! • No direct access to fields! private decimal _x = 0; public decimal X { get { return _x; } set { _x = value; } } • No assumptions about class clients! // param2 should be > 0, in other case method fails public int Method(int param1, int param2) !
  • 57. Inheritance! Should be able to say that child ‘is’ parent! Circle is Shape HtmlParser is Parser! Does code follow the principle?! class Customer { public int ID { get; set; } public string Name { get; set; } } class Bank: Customer { public string CorrespondentAccount { get; set; } } Depends on whether a bank can be a customer or not! !
  • 58. Inheritance! Move common methods to base class! abstract class Stream { public void Write(byte[] bytes); public byte[] Read(); } class SecureStream: Stream { public void Init(StreamConfig config); } !
  • 59. Inheritance! Avoid following situations:! • Parent class has only one child! • Child overrides method leaving it empty! • Too many hierarchy levels! better not more than 3 levels!
  • 60. Comments! Commenting principles. Bad comments. Good comments.!
  • 61. Commenting Principles! • Comments do not redress bad code! clean code much better than bad code with comments! • Do not comment tricky code – rewrite it! tricky code = bad code! • Try to explain with code! // is employee eligible for bonus if ((employee.Schedule == HOURLY_SCHEDULE) && employee.Age > 65) { … } ! Better! if (employee.IsEligibleForBonus()) { … }
  • 62. Commenting Principles! Comment says “why” not “how”! • How! // if flag equals to zero if (accountFlag == 0) • Why! // if new account created if (accountFlag == 0) • Code instead of comment! if (accountType == AccountType.NewAccount)
  • 63. Bad Comments! • Redundant comments! obvious and repeating code! // closing connection Connection.Close(); • Commented code! remove unnecessary code, VCS is for the rescue InputStream response = new InputStream(); response.SetBody(formatter.ResultStream, formatter.BytesCount); //InputStream resultStream = formatter.ResultStream; //StreamReader reader = new StreamReader(resultStream); //response.SetContent(reader.Read(formatter.BytesCount));
  • 64. Good Comments! • Legal comments! license, copyright, author! • Explanations! provide info about inevitable tricks // NOTE: postpone execution to refresh UI setTimeout(function() { // code }); • TODOs! notes for future to avoid “broken windows” // TODO: get rid of tricky workaround function badFunction() { // tricky workaround here });
  • 65. Thank you!! Your questions, please!! ARTEM TABALIN!
  • 66. References! • Steve McConnell Code Complete! • Robert C. Martin Clean Code! • Hunt A., Thomas D. The Pragmatic Programmer ! • Craig Larman Applying UML and Patterns! • Kent Beck Implementation Patterns! • Eric Evans Domain-Driven Design!