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

PDF
How to use Flux (pattern) in React?
PDF
A guide to hiring a great developer to build your first app (redacted version)
PDF
How to build a Whatsapp clone in 2 hours
PPTX
HTML5 Bootcamp: Essential HTML, CSS, & JavaScript
PDF
Bootstrap4 與他的好搭檔
PDF
Launching Ruby on Rails projects: A checklist
PDF
瓶頸處理九大原則 (精簡版)
PDF
English curriculum guide grades 1 10 december 2013
How to use Flux (pattern) in React?
A guide to hiring a great developer to build your first app (redacted version)
How to build a Whatsapp clone in 2 hours
HTML5 Bootcamp: Essential HTML, CSS, & JavaScript
Bootstrap4 與他的好搭檔
Launching Ruby on Rails projects: A checklist
瓶頸處理九大原則 (精簡版)
English curriculum guide grades 1 10 december 2013

Viewers also liked (14)

PPTX
PHP Powerpoint -- Teach PHP with this
PDF
How to Teach Yourself to Code
PDF
K to 12 General Presentation
PPT
Learn HTML & CSS From Scratch in 30 Days
PDF
How Not To Crumble Under Pressure
PDF
K to 12 Mathematics Curriculum Guide for Grades 1 to 10
ODP
PHP Web Programming
PDF
Must Haves For Small Business Growth
PDF
K to 12 Science Curriculum Guide
PPTX
大型 Web Application 轉移到 微服務的經驗分享
PPT
The Universe: A Module in Science and Technology for Grade 5 Pupils
PDF
How to write a good business letter
PDF
50 Ways to Become More Professionally Excellent
PPT
Personal SWOT for Teachers
PHP Powerpoint -- Teach PHP with this
How to Teach Yourself to Code
K to 12 General Presentation
Learn HTML & CSS From Scratch in 30 Days
How Not To Crumble Under Pressure
K to 12 Mathematics Curriculum Guide for Grades 1 to 10
PHP Web Programming
Must Haves For Small Business Growth
K to 12 Science Curriculum Guide
大型 Web Application 轉移到 微服務的經驗分享
The Universe: A Module in Science and Technology for Grade 5 Pupils
How to write a good business letter
50 Ways to Become More Professionally Excellent
Personal SWOT for Teachers
Ad

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

PDF
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
PDF
What is this DI and AOP stuff anyway...
PPT
Demystifying Maven
PDF
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
PDF
Having Fun with Kotlin Android - DILo Surabaya
PDF
Functional Reactive Programming on Android
PPTX
The Best Way to Become an Android Developer Expert with Android Jetpack
PDF
Purely Functional I/O
PDF
Android Security & Penetration Testing
PDF
XML-Free Programming : Java Server and Client Development without &lt;>
PDF
Practical pairing of generative programming with functional programming.
PDF
Workers of the web - BrazilJS 2013
PDF
Android and the Seven Dwarfs from Devox'15
PDF
Engineering culture
PDF
The Horoscope of OSGi: Meet Eclipse Libra, Virgo and Gemini (JavaOne 2013)
PDF
Symfony2 and MongoDB - MidwestPHP 2013
PDF
Dinosaurs and Androids: The Listview Evolution
PPTX
Building native Android applications with Mirah and Pindah
PDF
Serialization
PDF
Towards a software ecosystem for java prolog interoperabilty
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
What is this DI and AOP stuff anyway...
Demystifying Maven
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Having Fun with Kotlin Android - DILo Surabaya
Functional Reactive Programming on Android
The Best Way to Become an Android Developer Expert with Android Jetpack
Purely Functional I/O
Android Security & Penetration Testing
XML-Free Programming : Java Server and Client Development without &lt;>
Practical pairing of generative programming with functional programming.
Workers of the web - BrazilJS 2013
Android and the Seven Dwarfs from Devox'15
Engineering culture
The Horoscope of OSGi: Meet Eclipse Libra, Virgo and Gemini (JavaOne 2013)
Symfony2 and MongoDB - MidwestPHP 2013
Dinosaurs and Androids: The Listview Evolution
Building native Android applications with Mirah and Pindah
Serialization
Towards a software ecosystem for java prolog interoperabilty
Ad

Recently uploaded (20)

PDF
MCP Security Tutorial - Beginner to Advanced
PPTX
Patient Appointment Booking in Odoo with online payment
PDF
Visual explanation of Dijkstra's Algorithm using Python
DOCX
How to Use SharePoint as an ISO-Compliant Document Management System
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PDF
Salesforce Agentforce AI Implementation.pdf
PPTX
assetexplorer- product-overview - presentation
PPTX
Tech Workshop Escape Room Tech Workshop
PDF
Microsoft Office 365 Crack Download Free
PDF
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
PDF
Time Tracking Features That Teams and Organizations Actually Need
DOCX
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
PPTX
Trending Python Topics for Data Visualization in 2025
PDF
Cost to Outsource Software Development in 2025
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PDF
AI Guide for Business Growth - Arna Softech
PPTX
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
PDF
How Tridens DevSecOps Ensures Compliance, Security, and Agility
PDF
Website Design Services for Small Businesses.pdf
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
MCP Security Tutorial - Beginner to Advanced
Patient Appointment Booking in Odoo with online payment
Visual explanation of Dijkstra's Algorithm using Python
How to Use SharePoint as an ISO-Compliant Document Management System
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
Salesforce Agentforce AI Implementation.pdf
assetexplorer- product-overview - presentation
Tech Workshop Escape Room Tech Workshop
Microsoft Office 365 Crack Download Free
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
Time Tracking Features That Teams and Organizations Actually Need
Modern SharePoint Intranet Templates That Boost Employee Engagement in 2025.docx
Trending Python Topics for Data Visualization in 2025
Cost to Outsource Software Development in 2025
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
AI Guide for Business Growth - Arna Softech
WiFi Honeypot Detecscfddssdffsedfseztor.pptx
How Tridens DevSecOps Ensures Compliance, Security, and Agility
Website Design Services for Small Businesses.pdf
Why Generative AI is the Future of Content, Code & Creativity?

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
  • 51. Architecture The Lost Years http://www.youtube.com/watch? v=WpkDN78P884 The Web (Rails) is a Delivery Mechanism! 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)