SlideShare a Scribd company logo
Clean Code
⇧⌘K
Edwin Kwok
Monday, 11 March, 13
Provided to you by
Open source development kit for
mobile, web & IoT apps
Skygear.io
Skygear.io
Clean Code
Title: Clean Code: A
Handbook of Agile
Software
Craftsmanship
Author: Robert C.
Martin (Uncle Bob)
Monday, 11 March, 13
Skygear.io
Why Clean Code?
Monday, 11 March, 13
Skygear.io
Why Clean Code?
0
10
20
30
40
50
60
70
80
90
100
0 500 1000 2000 2500 3000 3500 4000
Productivity Ratio vs Time
Monday, 11 March, 13
Skygear.io
Smart vs Professional
Smart
Great Coding Skill
Write advanced code
String r; // lowercase url
Monday, 11 March, 13
Skygear.io
Smart vs Professional
Smart
Great Coding Skill
Write advanced code
String r; // lowercase url
Professional
Readable code
Maintainable code
String lowercaseUrl;
Monday, 11 March, 13
Skygear.io
Name
Choose your names thoughtfully
If a name requires a comment, the name
does not reveal its intent
Monday, 11 March, 13
Skygear.io
Name
Choose your names thoughtfully
If a name requires a comment, the name
does not reveal its intent
int d;
What does it mean? Days? Diameter?
Monday, 11 March, 13
Skygear.io
Name
Choose your names thoughtfully
If a name requires a comment, the name
does not reveal its intent
int d;
What does it mean? Days? Diameter?
int d; //elapsed time in days
Is this any better?
Monday, 11 March, 13
Skygear.io
Name
Choose your names thoughtfully
If a name requires a comment, the name
does not reveal its intent
int d;
What does it mean? Days? Diameter?
int elapsedTimeInDays;
What about this?
int d; //elapsed time in days
Is this any better?
Monday, 11 March, 13
Skygear.io
Name
Choose part of speech well
method / function => verb
class / object => noun
def authentication
# ...
end
def authenticate
# ...
end
Monday, 11 March, 13
Skygear.io
Name
use Pronounceable Names
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
private final String pszqint = “102”;
}
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;
private final String recordId = “102”;
}
Monday, 11 March, 13
Skygear.io
Names...
Avoid encodings
public class Part {
private String mName;
void setName(String name) {
mName = name;
}
}
public class Part {
private String name;
void setName(String name) {
this.name = name;
}
}
Hungarian notation
bBusy: boolean
chInitial: char
cApples: count of items
fpPrice: floating-point
dbPi: double (Systems)
pFoo: pointer
Monday, 11 March, 13
Skygear.io
Discussion:
Android vs IOS
ListView listView = new ListView(context);
listView.setAdapter(anAdapter);
UITableView tableView =
[[UITableView alloc]
initWithFrame:aFrame
style:UITableViewStylePlain];
tableView.datasource = aDataSource;
Android:
IOS:
Which one is better?
Monday, 11 March, 13
Skygear.io
Adapter
The adapter pattern is adapting between
classes and objects, like a bridge between
two objects.
e.g.
SimpleCursorAdapter
ArrayAdapter
Monday, 11 March, 13
Skygear.io
Adapter
Title: Design Patterns: Elements of
Reusable Object-Oriented Software
Author:
John Vlissides
Richard Helm
Ralph Johnson
Erich Gamma
Monday, 11 March, 13
Skygear.io
Use Case (Philips)
UITabBarController
Adapter
UITableViewController
Monday, 11 March, 13
Skygear.io
Use design pattern as name
Use Solution Domain Names, e.g.
AccountVisitor
JobQueue
LabelObserver
SimpleCursorAdapter
Monday, 11 March, 13
Skygear.io
Singleton
https://www.youtube.com/watch?v=-FRm3VPhseI
Monday, 11 March, 13
Skygear.io
Singleton
https://www.youtube.com/watch?v=-FRm3VPhseI
v.s.
Global Object
Monday, 11 March, 13
Skygear.io
Deceptive API
testCharge() {
CreditCard cc;
cc = new CreditCard(“1234567890121234”);
cc.charge(100);
}
java.lang.NullPointerException
at talk.CreditCard.charge(CreditCard.java:49)
Monday, 11 March, 13
Skygear.io
Deceptive API
testCharge() {
CreditCardProcessor.init(...);
CreditCard cc;
cc = new CreditCard(“1234567890121234”);
cc.charge(100);
}
java.lang.NullPointerException
at talk.CreditCardProcessor.init
(CreditCardProcessor.java:146)
Monday, 11 March, 13
Skygear.io
Deceptive API
testCharge() {
OffineQueue.start();
CreditCardProcessor.init(...);
CreditCard cc;
cc = new CreditCard(“1234567890121234”);
cc.charge(100);
}
java.lang.NullPointerException
at talk.OfflineQueue.start (OfflineQueue.java:16)
Monday, 11 March, 13
Skygear.io
Deceptive API
testCharge() {
Database.connect(...);
OffineQueue.start();
CreditCardProcessor.init(...);
CreditCard cc;
cc = new CreditCard(“1234567890121234”);
cc.charge(100);
}
CreditCard API lies
It pretends to not need the CreditCardProcessor
The API doesn’t tell the exact order of the
initialization
Monday, 11 March, 13
Skygear.io
Deceptive API
testCharge() {
database = new Database(...);
queue = new OfflineQueue(database);
creditCardProcessor = new CreditCardProcessor(queue);
CreditCard cc;
cc = new CreditCard(“1234567890121234”,
creditCardProcessor);
cc.charge(100);
}
Dependency injection enforces the order of
initialization at compile time.
Monday, 11 March, 13
Skygear.io
Discussion:
Object passing in Android?
How to pass objects to another Activity?
Monday, 11 March, 13
Skygear.io
Comment
Monday, 11 March, 13
Skygear.io
Comment
//* no Comments *//
Monday, 11 March, 13
Skygear.io
Comment
Comment doesn’t make your code becomes
good code
//* no Comments *//
Monday, 11 March, 13
Skygear.io
Good Comments
Informative Comments
// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timePattern =
Pattern.compile(
“d*:d*:d* w*, w* d*, d*”);
Todo Comments
/*
TODO: All calls to getPage should actually come
here, and be relative to the current page, not the
parent page. It was a gross error to have the whole
wiki know that references were relative to the
parent instead of the page.
*/
Pubic API documentation
Monday, 11 March, 13
Skygear.io
Bad Comments
Redundant Comments
/**
* The processor delay for this component.
*/
protected int backgroundProcessorDelay = -1;
/**
* The container event listeners for this Container.
*/
protected ArrayList listeners = new ArrayList();
Monday, 11 March, 13
Skygear.io
Bad Comments
Attribution Comments
/* Added by Gary */
Big Banner Comments
// **********************
// * Instance Variables *
// *********************
private int myVariable;
// ***********************
// * Default Constructor *
// ***********************
public MyClass() {}
Monday, 11 March, 13
Skygear.io
Mumbling
/* For bug FS-13005, we had to add this. The bug
was that the Now Playing screen was somehow being
launched, in that viewDidAppear was being called, but the view
was not being shown on the screen. The Now Playing screen then
when on to do all it's stuff and the user was left looking at an
incomplete Mode screen. So the "fix" is to kill off any residual Now
Playing screen that is under the Mode tab whenever we start a
new connection to a radio. */
What is
FS-13005?
Sorry! I have
no idea what you are talking about.
Monday, 11 March, 13
Skygear.io
Horizontal Alignment
@interface Tape : NSObject {
! NSString *_brushName;
! NSString *_headImageNamed;
! NSString *_bodyImageNamed;
! NSString *_tailImageNamed;
! CGFloat _opacity;
! BOOL! _includeShadow;
! NSString *_text;
! NSString *_fontName;
! CGFloat! _fontSize;
! NSString *_colorHex;
! NSDictionary *_all;
}
@interface Tape : NSObject {
! NSString *_brushName;
! NSString *_headImageNamed;
! NSString *_bodyImageNamed;
! NSString *_tailImageNamed;
! CGFloat _opacity;
! BOOL! _includeShadow;
! NSString *_text;
! NSString *_fontName;
! CGFloat! _fontSize;
! NSString *_colorHex;
! NSDictionary *_all;
}
Monday, 11 March, 13
Skygear.io
Function
should be Small
does one thing
the ideal number of arguments for a
function is .... 0
the less arguments, the better
try not to more than 3 arguments
Monday, 11 March, 13
Skygear.io
Function
No Side effects
// do something or answer something, but not both
public boolean set(String attribute, String value);
if (attributeExists(“username”)) {
setAttribute(“username”, “Ben”);
}
Monday, 11 March, 13
Skygear.io
Class
Avoid God Class
In OO, God Class is a class that does lots
of things
example: UITableViewController
Monday, 11 March, 13
Skygear.io
Data Structure and Object
public class Square {
public Point topLeft;
public double side;
}
public class Geometry {
public double calculateArea(Object shape)
throws noSuchShapeException {
if (shape instanceof Square) {
Square square = (Square)shape;
return square.side * square.side;
} else if (shape instanceof Rectangle) {
Rectangle rectangle = (Rectangle)shape;
return rectangle.height * rectangle.width;
}
throw new NoSuchShapeException();
}
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
Monday, 11 March, 13
Skygear.io
Data Structure and Object
public class Square implements Shape {
public Point topLeft;
public double side;
public double area() {
return side*side;
}
}
public class Rectangle implements Shape{
public Point topLeft;
public double height;
public double width;
public double area() {
return height * width;
}
}
Monday, 11 March, 13
Skygear.io
Data Structure and Object
Procedural Code (code using data structure)
Pros: easy to add new functions without
changing existing data structure
Cons: hard to add new data structure all
the functions must change
OO code
Pros: easy to add new classes without
changing existing function
Cons: hard to a new function as all classes
must change
Monday, 11 March, 13
Skygear.io
Data Structure and Object
Procedural Code (code using data structure)
Pros: easy to add new functions without
changing existing data structure
Cons: hard to add new data structure all
the functions must change
OO code
Pros: easy to add new classes without
changing existing function
Cons: hard to a new function as all classes
must change
Avoid Hybrids
Monday, 11 March, 13
Skygear.io
How About
ActiveRecord?
Monday, 11 March, 13
Error Handling
Prefer exceptions to returning error codes
if (deletePage(page) == E_OK) {
if (registry.deleteReference(page.name) == E_OK) {
if (configKeys.deleteKey(page.name.makeKey() == E_OK) {
logger.log(“page deleted”);
} else {
logger.log(“configKey not deleted”);
}
} else {
logger.log(“deleteReference from registry failed”);
}
} else {
logger.log(“delete failed”);
return E_ERROR;
}
Monday, 11 March, 13
Skygear.io
Error Handling
prefer exceptions to returning error codes
try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
easier to find the normal path
avoid nested conditions
Monday, 11 March, 13
Skygear.io
Error Handling
Don’t Return Null
List<Employee> employees = getEmployees();
if (employees != null) {
for (Employee e : employees) {
totalPay += e.getPay();
}
}
Monday, 11 March, 13
Skygear.io
Error Handling
Don’t Return Null
List<Employee> employees = getEmployees();
for (Employee e : employees) {
totalPay += e.getPay();
}
public List<Employee> getEmployees() {
if (/* there are no employees */) {
return Collections.emptyList();
}
}
Monday, 11 March, 13
Skygear.io
SOLID
Single Responsibility Principle
Open Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency inversion Principle
Monday, 11 March, 13
Skygear.io
Single Responsibility Principle
LabelBox Cloud Labels
Monday, 11 March, 13
Skygear.io
Architecture
Monday, 11 March, 13
Skygear.io
Monday, 11 March, 13
Skygear.io
Architecture
The Lost Years
http://www.youtube.com/watch?
v=WpkDN78P884
The Web (Rails) is a Delivery Mechanism!
Monday, 11 March, 13
Skygear.io
Test - a real scenario
...
client server
workerss3
1. upload a video
2. store in s3
3. start worker and
send request to worker
4. dedicated worker pulls the file
from s3 and do transcoding
Monday, 11 March, 13
Skygear.io
Test
Remove FEAR during Development
You know you break something during
testing.
For example:
Rugby - ~178 tests
Refer to Ben’s presentation
https://speakerdeck.com/oursky/testing
Monday, 11 March, 13
Skygear.io
Test
FIRST
Fast
Independent
Repeatable
Self-validating
Timely
Monday, 11 March, 13
Skygear.io
Refactor
Title:Refactoring: Improving the
Design of Existing Code
Author:
Martin Fowler
Kent Beck
John Brant
William Opdyke
Don Roberts
Monday, 11 March, 13
Skygear.io
Familiar With your Tools
try to familiar with your tools before coding,
don’t create messy stuffs by your first
impression
do testing before adopting to the real code
read the API, doc and Google
ask others ...
Monday, 11 March, 13
Skygear.io
Quiz (javascript)
The expected output of the following
javascript is alert count down from 5 to 0.
Explain why it doesn’t work and fix the bug.
function count (num) {
for (var i = 0; i <= num; i += 1) {
setTimeout(function () {
alert(num - i);
}, i * 1000);
}
}
count(5);
Monday, 11 March, 13
Skygear.io
Quiz (javascript)
function count (num) {
for (var i = 0; i <= num; i += 1) {
(function (time) {
setTimeout(function () {
alert(num - time);
}, time * 1000);
}(i));
}
}
count(5);
Monday, 11 March, 13
Skygear.ioSkygear.io
Quiz (javascript) cont.
function changeAnchorsToLightBox(anchors) {
var length = anchors.length;
for (var i = 0; i < length; i++) {
anchors[i].onclick = function () {
lightBox.open(anchors[i]);
return false;
};
}
}
Monday, 11 March, 13
Skygear.io
Quiz (javascript) cont.
function changeAnchorsToLightBox(anchors) {
var length = anchors.length;
for (var i = 0; i < length; i++) {
(function (anchor) {
anchor.onclick = function () {
lightBox.open(anchor);
return false;
};
}(anchors[i]));
}
}
Monday, 11 March, 13
Skygear.io
Quiz (javascript) cont.
function changeAnchorsToLightBox(anchors) {
var length = anchors.length;
for (var i = 0; i < length; i++) {
(function (anchor) {
anchor.onclick = function () {
lightBox.open(anchor);
return false;
};
}(anchors[i]));
}
}
Monday, 11 March, 13
Skygear.io
Reference
Clean Code: A Handbook of Agile Software
Craftsmanship
http://www.amazon.com/Clean-Code-Handbook-
Software-Craftsmanship/dp/0132350882
The Clean Code Talks - "Global State and
Singletons"
https://www.youtube.com/watch?v=-FRm3VPhseI
Monday, 11 March, 13
Skygear.io
Q & A and ...
“Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.”
Martin Fowler:
Monday, 11 March, 13
Skygear.io
Brought to you by Oursky
Build your mobile app fast
skygear.io (open source)

More Related Content

Viewers also liked (14)

PPTX
PHP Powerpoint -- Teach PHP with this
Ian Macali
 
PDF
How to Teach Yourself to Code
Mattan Griffel
 
PDF
K to 12 General Presentation
DepEdPhilippines
 
PPT
Learn HTML & CSS From Scratch in 30 Days
Jonathan Grover
 
PDF
How Not To Crumble Under Pressure
Faisal Hoque
 
PDF
K to 12 Mathematics Curriculum Guide for Grades 1 to 10
Dr. Joy Kenneth Sala Biasong
 
ODP
PHP Web Programming
Muthuselvam RS
 
PDF
Must Haves For Small Business Growth
Faisal Hoque
 
PDF
K to 12 Science Curriculum Guide
Dr. Joy Kenneth Sala Biasong
 
PPTX
大型 Web Application 轉移到 微服務的經驗分享
Andrew Wu
 
PPT
The Universe: A Module in Science and Technology for Grade 5 Pupils
cryster
 
PDF
How to write a good business letter
Sukh Sandhu
 
PDF
50 Ways to Become More Professionally Excellent
Leslie Bradshaw
 
PPT
Personal SWOT for Teachers
m nagaRAJU
 
PHP Powerpoint -- Teach PHP with this
Ian Macali
 
How to Teach Yourself to Code
Mattan Griffel
 
K to 12 General Presentation
DepEdPhilippines
 
Learn HTML & CSS From Scratch in 30 Days
Jonathan Grover
 
How Not To Crumble Under Pressure
Faisal Hoque
 
K to 12 Mathematics Curriculum Guide for Grades 1 to 10
Dr. Joy Kenneth Sala Biasong
 
PHP Web Programming
Muthuselvam RS
 
Must Haves For Small Business Growth
Faisal Hoque
 
K to 12 Science Curriculum Guide
Dr. Joy Kenneth Sala Biasong
 
大型 Web Application 轉移到 微服務的經驗分享
Andrew Wu
 
The Universe: A Module in Science and Technology for Grade 5 Pupils
cryster
 
How to write a good business letter
Sukh Sandhu
 
50 Ways to Become More Professionally Excellent
Leslie Bradshaw
 
Personal SWOT for Teachers
m nagaRAJU
 

Similar to How to write better code: in-depth best practices for writing readable, simple, extendable and efficient code (Part I) (20)

PDF
Iphone lecture imp
Pragati Singh
 
PDF
Programming iOS 5 2nd Edition Matt Neuburg
saertahai
 
PDF
Game Programming 04 - Style & Design Principles
Nick Pruehs
 
PPTX
Code Quality Management iOS
Arpit Kulsreshtha
 
PDF
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
assangkaoua
 
PDF
Symbian OS - Mopoid Next Gen - Slides
Andreas Jakl
 
KEY
Objective c
Stijn
 
PDF
Programming Ios 4 Fundamentals Of Iphone Ipad And Ipod Touch Development 1st ...
jungieaugi
 
ODP
Preventing Complexity in Game Programming
Yaser Zhian
 
PDF
Assignment2 B Walkthrough
Mahmoud
 
PDF
Architecting iOS Project
Massimo Oliviero
 
PDF
200910 - iPhone at OOPSLA
Javier Gonzalez-Sanchez
 
PPTX
Software Design
Ahmed Misbah
 
PPTX
iOS Coding Best Practices
Jean-Luc David
 
PDF
Advanced iOS
Pete Goodliffe
 
PPTX
iOS,From Development to Distribution
Tunvir Rahman Tusher
 
PPT
Object oriented analysis_and_design_v2.0
Ganapathi M
 
PDF
Programming Ios 5 2nd Edition 2nd Early Release Draft Matt Neuburg
lindzpeccoo
 
PDF
Objective-C
Abdlhadi Oul
 
Iphone lecture imp
Pragati Singh
 
Programming iOS 5 2nd Edition Matt Neuburg
saertahai
 
Game Programming 04 - Style & Design Principles
Nick Pruehs
 
Code Quality Management iOS
Arpit Kulsreshtha
 
Programming iOS 4 Fundamentals of iPhone iPad and iPod Touch Development 1st ...
assangkaoua
 
Symbian OS - Mopoid Next Gen - Slides
Andreas Jakl
 
Objective c
Stijn
 
Programming Ios 4 Fundamentals Of Iphone Ipad And Ipod Touch Development 1st ...
jungieaugi
 
Preventing Complexity in Game Programming
Yaser Zhian
 
Assignment2 B Walkthrough
Mahmoud
 
Architecting iOS Project
Massimo Oliviero
 
200910 - iPhone at OOPSLA
Javier Gonzalez-Sanchez
 
Software Design
Ahmed Misbah
 
iOS Coding Best Practices
Jean-Luc David
 
Advanced iOS
Pete Goodliffe
 
iOS,From Development to Distribution
Tunvir Rahman Tusher
 
Object oriented analysis_and_design_v2.0
Ganapathi M
 
Programming Ios 5 2nd Edition 2nd Early Release Draft Matt Neuburg
lindzpeccoo
 
Objective-C
Abdlhadi Oul
 
Ad

Recently uploaded (20)

PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PPTX
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PDF
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
Ad

How to write better code: in-depth best practices for writing readable, simple, extendable and efficient code (Part I)

  • 1. Clean Code ⇧⌘K Edwin Kwok Monday, 11 March, 13 Provided to you by Open source development kit for mobile, web & IoT apps Skygear.io Skygear.io
  • 2. Clean Code Title: Clean Code: A Handbook of Agile Software Craftsmanship Author: Robert C. Martin (Uncle Bob) Monday, 11 March, 13 Skygear.io
  • 3. Why Clean Code? Monday, 11 March, 13 Skygear.io
  • 4. Why Clean Code? 0 10 20 30 40 50 60 70 80 90 100 0 500 1000 2000 2500 3000 3500 4000 Productivity Ratio vs Time Monday, 11 March, 13 Skygear.io
  • 5. Smart vs Professional Smart Great Coding Skill Write advanced code String r; // lowercase url Monday, 11 March, 13 Skygear.io
  • 6. Smart vs Professional Smart Great Coding Skill Write advanced code String r; // lowercase url Professional Readable code Maintainable code String lowercaseUrl; Monday, 11 March, 13 Skygear.io
  • 7. Name Choose your names thoughtfully If a name requires a comment, the name does not reveal its intent Monday, 11 March, 13 Skygear.io
  • 8. Name Choose your names thoughtfully If a name requires a comment, the name does not reveal its intent int d; What does it mean? Days? Diameter? Monday, 11 March, 13 Skygear.io
  • 9. Name Choose your names thoughtfully If a name requires a comment, the name does not reveal its intent int d; What does it mean? Days? Diameter? int d; //elapsed time in days Is this any better? Monday, 11 March, 13 Skygear.io
  • 10. Name Choose your names thoughtfully If a name requires a comment, the name does not reveal its intent int d; What does it mean? Days? Diameter? int elapsedTimeInDays; What about this? int d; //elapsed time in days Is this any better? Monday, 11 March, 13 Skygear.io
  • 11. Name Choose part of speech well method / function => verb class / object => noun def authentication # ... end def authenticate # ... end Monday, 11 March, 13 Skygear.io
  • 12. Name use Pronounceable Names class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = “102”; } class Customer { private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = “102”; } Monday, 11 March, 13 Skygear.io
  • 13. Names... Avoid encodings public class Part { private String mName; void setName(String name) { mName = name; } } public class Part { private String name; void setName(String name) { this.name = name; } } Hungarian notation bBusy: boolean chInitial: char cApples: count of items fpPrice: floating-point dbPi: double (Systems) pFoo: pointer Monday, 11 March, 13 Skygear.io
  • 14. Discussion: Android vs IOS ListView listView = new ListView(context); listView.setAdapter(anAdapter); UITableView tableView = [[UITableView alloc] initWithFrame:aFrame style:UITableViewStylePlain]; tableView.datasource = aDataSource; Android: IOS: Which one is better? Monday, 11 March, 13 Skygear.io
  • 15. Adapter The adapter pattern is adapting between classes and objects, like a bridge between two objects. e.g. SimpleCursorAdapter ArrayAdapter Monday, 11 March, 13 Skygear.io
  • 16. Adapter Title: Design Patterns: Elements of Reusable Object-Oriented Software Author: John Vlissides Richard Helm Ralph Johnson Erich Gamma Monday, 11 March, 13 Skygear.io
  • 18. Use design pattern as name Use Solution Domain Names, e.g. AccountVisitor JobQueue LabelObserver SimpleCursorAdapter Monday, 11 March, 13 Skygear.io
  • 21. Deceptive API testCharge() { CreditCard cc; cc = new CreditCard(“1234567890121234”); cc.charge(100); } java.lang.NullPointerException at talk.CreditCard.charge(CreditCard.java:49) Monday, 11 March, 13 Skygear.io
  • 22. Deceptive API testCharge() { CreditCardProcessor.init(...); CreditCard cc; cc = new CreditCard(“1234567890121234”); cc.charge(100); } java.lang.NullPointerException at talk.CreditCardProcessor.init (CreditCardProcessor.java:146) Monday, 11 March, 13 Skygear.io
  • 23. Deceptive API testCharge() { OffineQueue.start(); CreditCardProcessor.init(...); CreditCard cc; cc = new CreditCard(“1234567890121234”); cc.charge(100); } java.lang.NullPointerException at talk.OfflineQueue.start (OfflineQueue.java:16) Monday, 11 March, 13 Skygear.io
  • 24. Deceptive API testCharge() { Database.connect(...); OffineQueue.start(); CreditCardProcessor.init(...); CreditCard cc; cc = new CreditCard(“1234567890121234”); cc.charge(100); } CreditCard API lies It pretends to not need the CreditCardProcessor The API doesn’t tell the exact order of the initialization Monday, 11 March, 13 Skygear.io
  • 25. Deceptive API testCharge() { database = new Database(...); queue = new OfflineQueue(database); creditCardProcessor = new CreditCardProcessor(queue); CreditCard cc; cc = new CreditCard(“1234567890121234”, creditCardProcessor); cc.charge(100); } Dependency injection enforces the order of initialization at compile time. Monday, 11 March, 13 Skygear.io
  • 26. Discussion: Object passing in Android? How to pass objects to another Activity? Monday, 11 March, 13 Skygear.io
  • 27. Comment Monday, 11 March, 13 Skygear.io
  • 28. Comment //* no Comments *// Monday, 11 March, 13 Skygear.io
  • 29. Comment Comment doesn’t make your code becomes good code //* no Comments *// Monday, 11 March, 13 Skygear.io
  • 30. Good Comments Informative Comments // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timePattern = Pattern.compile( “d*:d*:d* w*, w* d*, d*”); Todo Comments /* TODO: All calls to getPage should actually come here, and be relative to the current page, not the parent page. It was a gross error to have the whole wiki know that references were relative to the parent instead of the page. */ Pubic API documentation Monday, 11 March, 13 Skygear.io
  • 31. Bad Comments Redundant Comments /** * The processor delay for this component. */ protected int backgroundProcessorDelay = -1; /** * The container event listeners for this Container. */ protected ArrayList listeners = new ArrayList(); Monday, 11 March, 13 Skygear.io
  • 32. Bad Comments Attribution Comments /* Added by Gary */ Big Banner Comments // ********************** // * Instance Variables * // ********************* private int myVariable; // *********************** // * Default Constructor * // *********************** public MyClass() {} Monday, 11 March, 13 Skygear.io
  • 33. Mumbling /* For bug FS-13005, we had to add this. The bug was that the Now Playing screen was somehow being launched, in that viewDidAppear was being called, but the view was not being shown on the screen. The Now Playing screen then when on to do all it's stuff and the user was left looking at an incomplete Mode screen. So the "fix" is to kill off any residual Now Playing screen that is under the Mode tab whenever we start a new connection to a radio. */ What is FS-13005? Sorry! I have no idea what you are talking about. Monday, 11 March, 13 Skygear.io
  • 34. Horizontal Alignment @interface Tape : NSObject { ! NSString *_brushName; ! NSString *_headImageNamed; ! NSString *_bodyImageNamed; ! NSString *_tailImageNamed; ! CGFloat _opacity; ! BOOL! _includeShadow; ! NSString *_text; ! NSString *_fontName; ! CGFloat! _fontSize; ! NSString *_colorHex; ! NSDictionary *_all; } @interface Tape : NSObject { ! NSString *_brushName; ! NSString *_headImageNamed; ! NSString *_bodyImageNamed; ! NSString *_tailImageNamed; ! CGFloat _opacity; ! BOOL! _includeShadow; ! NSString *_text; ! NSString *_fontName; ! CGFloat! _fontSize; ! NSString *_colorHex; ! NSDictionary *_all; } Monday, 11 March, 13 Skygear.io
  • 35. Function should be Small does one thing the ideal number of arguments for a function is .... 0 the less arguments, the better try not to more than 3 arguments Monday, 11 March, 13 Skygear.io
  • 36. Function No Side effects // do something or answer something, but not both public boolean set(String attribute, String value); if (attributeExists(“username”)) { setAttribute(“username”, “Ben”); } Monday, 11 March, 13 Skygear.io
  • 37. Class Avoid God Class In OO, God Class is a class that does lots of things example: UITableViewController Monday, 11 March, 13 Skygear.io
  • 38. Data Structure and Object public class Square { public Point topLeft; public double side; } public class Geometry { public double calculateArea(Object shape) throws noSuchShapeException { if (shape instanceof Square) { Square square = (Square)shape; return square.side * square.side; } else if (shape instanceof Rectangle) { Rectangle rectangle = (Rectangle)shape; return rectangle.height * rectangle.width; } throw new NoSuchShapeException(); } } public class Rectangle { public Point topLeft; public double height; public double width; } Monday, 11 March, 13 Skygear.io
  • 39. Data Structure and Object public class Square implements Shape { public Point topLeft; public double side; public double area() { return side*side; } } public class Rectangle implements Shape{ public Point topLeft; public double height; public double width; public double area() { return height * width; } } Monday, 11 March, 13 Skygear.io
  • 40. Data Structure and Object Procedural Code (code using data structure) Pros: easy to add new functions without changing existing data structure Cons: hard to add new data structure all the functions must change OO code Pros: easy to add new classes without changing existing function Cons: hard to a new function as all classes must change Monday, 11 March, 13 Skygear.io
  • 41. Data Structure and Object Procedural Code (code using data structure) Pros: easy to add new functions without changing existing data structure Cons: hard to add new data structure all the functions must change OO code Pros: easy to add new classes without changing existing function Cons: hard to a new function as all classes must change Avoid Hybrids Monday, 11 March, 13 Skygear.io
  • 43. Error Handling Prefer exceptions to returning error codes if (deletePage(page) == E_OK) { if (registry.deleteReference(page.name) == E_OK) { if (configKeys.deleteKey(page.name.makeKey() == E_OK) { logger.log(“page deleted”); } else { logger.log(“configKey not deleted”); } } else { logger.log(“deleteReference from registry failed”); } } else { logger.log(“delete failed”); return E_ERROR; } Monday, 11 March, 13 Skygear.io
  • 44. Error Handling prefer exceptions to returning error codes try { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); } catch (Exception e) { logger.log(e.getMessage()); } easier to find the normal path avoid nested conditions Monday, 11 March, 13 Skygear.io
  • 45. Error Handling Don’t Return Null List<Employee> employees = getEmployees(); if (employees != null) { for (Employee e : employees) { totalPay += e.getPay(); } } Monday, 11 March, 13 Skygear.io
  • 46. Error Handling Don’t Return Null List<Employee> employees = getEmployees(); for (Employee e : employees) { totalPay += e.getPay(); } public List<Employee> getEmployees() { if (/* there are no employees */) { return Collections.emptyList(); } } Monday, 11 March, 13 Skygear.io
  • 47. SOLID Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency inversion Principle Monday, 11 March, 13 Skygear.io
  • 48. Single Responsibility Principle LabelBox Cloud Labels Monday, 11 March, 13 Skygear.io
  • 50. Monday, 11 March, 13 Skygear.io
  • 52. Test - a real scenario ... client server workerss3 1. upload a video 2. store in s3 3. start worker and send request to worker 4. dedicated worker pulls the file from s3 and do transcoding Monday, 11 March, 13 Skygear.io
  • 53. Test Remove FEAR during Development You know you break something during testing. For example: Rugby - ~178 tests Refer to Ben’s presentation https://speakerdeck.com/oursky/testing Monday, 11 March, 13 Skygear.io
  • 55. Refactor Title:Refactoring: Improving the Design of Existing Code Author: Martin Fowler Kent Beck John Brant William Opdyke Don Roberts Monday, 11 March, 13 Skygear.io
  • 56. Familiar With your Tools try to familiar with your tools before coding, don’t create messy stuffs by your first impression do testing before adopting to the real code read the API, doc and Google ask others ... Monday, 11 March, 13 Skygear.io
  • 57. Quiz (javascript) The expected output of the following javascript is alert count down from 5 to 0. Explain why it doesn’t work and fix the bug. function count (num) { for (var i = 0; i <= num; i += 1) { setTimeout(function () { alert(num - i); }, i * 1000); } } count(5); Monday, 11 March, 13 Skygear.io
  • 58. Quiz (javascript) function count (num) { for (var i = 0; i <= num; i += 1) { (function (time) { setTimeout(function () { alert(num - time); }, time * 1000); }(i)); } } count(5); Monday, 11 March, 13 Skygear.ioSkygear.io
  • 59. Quiz (javascript) cont. function changeAnchorsToLightBox(anchors) { var length = anchors.length; for (var i = 0; i < length; i++) { anchors[i].onclick = function () { lightBox.open(anchors[i]); return false; }; } } Monday, 11 March, 13 Skygear.io
  • 60. Quiz (javascript) cont. function changeAnchorsToLightBox(anchors) { var length = anchors.length; for (var i = 0; i < length; i++) { (function (anchor) { anchor.onclick = function () { lightBox.open(anchor); return false; }; }(anchors[i])); } } Monday, 11 March, 13 Skygear.io
  • 61. Quiz (javascript) cont. function changeAnchorsToLightBox(anchors) { var length = anchors.length; for (var i = 0; i < length; i++) { (function (anchor) { anchor.onclick = function () { lightBox.open(anchor); return false; }; }(anchors[i])); } } Monday, 11 March, 13 Skygear.io
  • 62. Reference Clean Code: A Handbook of Agile Software Craftsmanship http://www.amazon.com/Clean-Code-Handbook- Software-Craftsmanship/dp/0132350882 The Clean Code Talks - "Global State and Singletons" https://www.youtube.com/watch?v=-FRm3VPhseI Monday, 11 March, 13 Skygear.io
  • 63. Q & A and ... “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” Martin Fowler: Monday, 11 March, 13 Skygear.io
  • 64. Brought to you by Oursky Build your mobile app fast skygear.io (open source)