(if...else, while)
let Erica, Jeff, Alex;
OnceJeffKillErica();
function OnceJeffKillErica() {
if (Jeff kill Erica) {
Alex is crying
Alex kill Jeff
if (Jeff is dead){
Alex get in jail
if...
} else {
...
}
}
}
let Erica, Jeff, Alex;
OnceJeffKillErica();
function OnceJeffKillErica() {
if (Jeff kill Erica) {
JeffGetRevenge()
}
}
function JeffGetRevenge () {
Alex is crying
Alex kill Jeff
if (Jeff is dead){
AlexGetConsequence()
} else {
...
}
}
funciton AlexGetConsequence () {
Alex get in jail
if ()...
}
Function name as responsibility
Extract another function only with restate its implementation.
function emailClients(clients) {
clients.forEach((client) => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
function emailActiveClients(clients) {
clients
.filter(isActiveClient)
.forEach(email);
}
function isActiveClient(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
function parseBetterJSAlternative(code) {
const REGEXES = [
// ...
];
const statements = code.split(' ');
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
// ...
});
});
const ast = [];
tokens.forEach((token) => {
// lex...
});
ast.forEach((node) => {
// parse...
});
}
function parseBetterJSAlternative(code) {
const tokens = tokenize(code);
const ast = lexer(tokens);
ast.forEach((node) => {
// parse...
});
}
function tokenize(code) {
const REGEXES = [
// ...
];
const statements = code.split(' ');
const tokens = [];
REGEXES.forEach((REGEX) => {
statements.forEach((statement) => {
tokens.push( /* ... */ );
});
});
return tokens;
}
function lexer(tokens) {
const ast = [];
tokens.forEach((token) => {
ast.push( /* ... */ );
});
return ast;
}
class Airplane {
// ...
getCruisingAltitude() {
switch (this.type) {
case '777':
return this.getMaxAltitude() - this.getPassengerCount();
case 'Air Force One':
return this.getMaxAltitude();
case 'Cessna':
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
}
class Airplane {
// ...
}
class Boeing777 extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount();
}
}
class AirForceOne extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude();
}
}
class Cessna extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
Use a naming convention
example:
addToDate -> addMonthToDate
function createMenu(title, body, buttonText, cancellable) {
// ...
}
function createMenu({ title, body, buttonText, cancellable }) {
// ...
}
createMenu({
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
});
function createFile(name, temp) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`);
}
Can't avoid in some case
Point p = new Point(0,0);
Circle makeCircle(x, y, radius);
Circle makeCircle({x, y, radius});
String.format(”%s worked %.2f hours.”, name, hours);
const addItemToCart = (cart, item) => {
cart.push({ item, date: Date.now() });
};
const addItemToCart = (cart, item) => {
return [...cart, { item, date: Date.now() }];
};
public boolean set(String attribute, String value);
if (set(”username”, ”unclebob”))…
if (get(”username”, ”unclebob”))…
if (deletePage(page) === true) {...}
try {
deletePage(page) === true)
...
} cache(e) {...}
try {
deletePageAndAllReferences(page);
}
catch (Exception e) {
logError(e);
}
Writing software is like any other kind of writing, no need to be perfect at first
Short, well named, and nicely organized
Most importantly: