This document provides a summary of a presentation on object-oriented programming (OOP) and clean code given at IPB Computer Science on March 28, 2017. It introduces the speaker, Ifnu Bima, and his background working at Deutsche Bank and blibli.com. The presentation covers topics like code quality metrics, meaningful naming conventions, high-quality functions, comments, and unit testing. It emphasizes writing code that is easy to maintain and modify over time to prevent issues like bugs and technical debt.
2. Who am I?
• Ifnu Bima
• Ilmu Komputer IPB, 38
• Join blibli in 2012
• Was working for Deustche Bank Singapore
• Employee no 69
• Engineers no ~13
• Development Manager
– blibli.com Web UI
– Mobile Apps : Android, iOS, Windows Phone
– Content Management System
– Search
– Product Discovery : Wishlist, Product Review
13. What Prevents Clean Code?
Number one reason:
“I’ll clean it up later.”
“Ahh, gampang, ntar
aja, yang penting
beres dulu”
14. The Truth about Clean Code
• Clean Code saves time.
• We can’t take a short-term view of software.
• We need to look at the lifespan of the
application.
15. How Do You Write Clean Code?
Rule of Thumb:
Imagine that the developer who
comes after you is a homicidal
maniac who knows where you
live.
-Unknown
19. Clean Code : Meaningful Names
• Intention-Revealing Names
• Self Explained Names
• theList, x1, y1, i, j, k, index
– Not very good
• productList, indexOfProductList
– A bit better
20. Intention-Revealing Names : Bad
List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList) {
if (x[0] == 4) {
list1.add(x);
}
}
return list1;
}
21. Intention-Revealing Names : Good
List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard) {
if (cell.isFlagged()) {
flaggedCells.add(cell);
}
}
return flaggedCells;
}
22. Clean Code : Meaningful Names
• Avoid Disinformation
int a = l;
if (O == l) a = O1;
else l = 01;
• Make Meaningful Distinctions
public static void copyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i];
}
}
23. Meaningful Names
• Use Pronounceable Names : Bad
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
/* ... */
}
• Use Pronounceable Names : Good
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;
private final String recordId = "102";
/* ... */ };
}
24. Meaningful Names
• Use Searchable Names : Bad
for (int j = 0; j < 34; j++) {
s += (t[j] * 4) / 5;
}
• Use Searchable Names : Good
int realDaysPerIdealDay = 4;const
int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j = 0; j < NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
25. Meaningful Names
• Avoid mental mapping : Bad
for (i = 0; i < arr.length; i++) {
for (j = i; j < arr.length; j++) {
//bubble sort
}
}
• Dont try to be funny : Bad
public void canggih() {
//TODO
}
27. High Quality Function
• Small!
• rules of functions:
1. should be small
2. should be smaller than that
• < 150 characters per line
• < 20 lines
• Do One Thing
1. FUNCTIONS SHOULD DO ONE THING. THEY
SHOULD DO IT WELL.
2. THEY SHOULD DO IT ONLY.
28. High Quality Function
• DRY : Dont repeat yourself
– Copy paste code everywhere is root of all evil in
software
29. Comments
• Do Not Make Up for Bad Code
– don’t comment bad code, rewrite it!
//edan ini kode siapa yang bikin!!
for (int j = 0; j < 34; j++) {
s += (t[j] * 4) / 5;
}
• Explain yourself in code
// Check to see if the employee is eligible for full
// benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
{
if (employee.isEligibleForFullBenefits()) {
}
}
30. Comments (good)
• Legal Comments
// Copyright (C) 2017 by blibli.com. All rights reserved.
// Released under the terms of the GNU General Public License
// version 2 or later
• Informative Comments
// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();
// format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile(
"d*:d*:d* w*, w* d*, d*");
31. Comments (good)
• Explanation of Intent
//This is our best attempt to get a race condition
//by creating large number of threads.
for (int i = 0; i < 25000; i++) {
WidgetBuilderThread widgetBuilderThread =
new WidgetBuilderThread(
widgetBuilder, text, failFlag);
Thread thread =
new Thread(widgetBuilderThread);
thread.start();
}
32. Comments (good)
• Clarification
assertTrue(a.compareTo(b) == -1); // a < b
assertTrue(b.compareTo(a) == 1); // b > a
• Warning of Consequences
public static SimpleDateFormat
makeStandardHttpDateFormat() {
//SimpleDateFormat is not thread safe,
//so we need to create each instance independently.
SimpleDateFormat df =
new SimpleDateFormat("dd MM yyyy");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
33. Comments (good)
• TODO Comments
//TODO - MdM these are not needed
//We expect this to go away when we do the checkout model
• Amplification
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list.
new ListItemWidget(this, listItemContent,
this.level + 1);
return buildList(text.substring(match.end()));
34. Comments (bad)
• Mumbling
try {
String propertiesPath = propertiesLocation
+ "/" + PROPERTIES_FILE;
FileInputStream propertiesStream =
new FileInputStream(propertiesPath);
loadedProperties.load(propertiesStream);
} catch (IOException e) {
// No properties files means all defaults are loaded
}
35. Comments (bad)
• Redundant Comments
/** * The processor delay for this component. */
protected int backgroundProcessorDelay = -1;
/** * The lifecycle event support for this component. */
protected LifecycleSupport lifecycle =
new LifecycleSupport(this);
/** * The container event listeners for this Container. */
protected ArrayList listeners = new ArrayList();
36. Comments (bad)
• Mandated Comments
/**
* @param title The title of the CD
* @param author The author of the CD
* @param tracks The number of tracks on the CD
* @param durationInMinutes The duration of the CD in minutes
*/
public void addCD(String title, String author,
int tracks, int durationInMinutes) {
CD cd = new CD();
cd.title = title;
cd.author = author;
cd.tracks = tracks;
cd.duration = durationInMinutes;
}
37. Comments (bad)
• Journal Comments
/** Changes (from 11-Oct-2001)
* --------------------------
* 11-Oct-2001 : Re-organised the class and moved it to new
* package com.jrefinery.date (DG);
* 05-Nov-2001 : Added a getDescription() method, and
* eliminated NotableDate class (DG);
* 12-Nov-2001 : IBD requires setDescription() method, now
* that NotableDate class is gone (DG); Changed
* getPreviousDayOfWeek(),
* getFollowingDayOfWeek() and
* getNearestDayOfWeek() to correct bugs (DG);
* 05-Dec-2001 : Fixed bug in SpreadsheetDate class (DG);
* 29-May-2002 : Moved the month constants into a separate
* interface (MonthConstants) (DG);
*/
38. Comments (bad)
• Noise Comments
/**
* Default constructor.
*/
protected AnnualDateRule() {
}
/**
* The day of the month.
*/
private int dayOfMonth;
/**
* Returns the day of the month.
* @return the day of the month.
*/
public int getDayOfMonth() {
return dayOfMonth;
}
39. Comments (bad)
• Scary Noise
/**
* The name.
*/
private String name;
/**
* The version.
*/
private String version;
/**
* The licenceName.
*/
private String licenceName;
/**
* The version.
*/
private String info;
40. Comments (bad)
• Position Markers
// Actions //////////////////////////////////
//End of Actions ///////////////////////////
41. Comments (bad)
• All sort of funny comments and stupid code
// For the sins I am about to commit, may James Gosling forgive me
// If this code works, it was written by Ifnu.
// If not, I don’t know who wrote it
Exception up = new Exception(“Something is really wrong.”);
throw up; //ha ha
//When I wrote this, only God and I understood what I was doing
//Now, God only knows
// I dedicate all this code, all my work, to my wife, Dian, who will
// have to support me and our two children and the cupang once it gets
// released into the public.
42. • All sort of funny comment and stupid code
//Dear future me. Please forgive me.
//I can’t even begin to express how sorry I am.
// Magic. Do not touch.
return 1; # returns 1
/////////////////////////////////////// this is a well
commented line
// I am not sure if we need this, but too scared to
delete.
// I am not responsible of this code.
// They made me write it, against my will.
// If I from the future read this I’ll back in time and
kill myself.
43. Unit Test
• Mengetes logic aplikasi secara otomatis dan
berulang-ulang
• Menghindarkan developer mengetes dengan
manual menggunkan mata
• Menghindari “regression bug”: mengubah
satu kode membuat kode lain jadi error
44. Unit Test
• Membuat developer percaya diri untuk
melakukan refactoring karena ada Unit Testing
• Digunakan secara luas sebagai ukuran internal
code quality
• JUnit secara de facto diterima sebagai tools
untuk Unit Testing di Java