“A code smell is a surface indication that usually corresponds to a deeper problem in the system.” Martin Fowler
“Bad code smells can be an indicator of factors that contribute to technical debt.” Robert C. Martin
“ Technical debt is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy solution now instead of using a better approach that would take longer.”
const users = [
{
id: 1,
name: "Carlos Caballero",
memberSince: "1997-04-20",
favoriteLanguageProgramming: ["JavaScript", "C", "Java"],
},
{
id: 2,
name: "Antonio Villena",
memberSince: "2014-08-15",
favoriteLanguageProgramming: ["Go", "Python", "JavaScript"],
},
{
id: 3,
name: "Jesús Segado",
memberSince: "2015-03-15",
favoriteLanguageProgramming: ["PHP", "JAVA", "JavaScript"],
}
];
const users = [
{ id: 1, name: "Carlos Caballero", memberSince: "1997-04-20", favoriteLanguageProgramming: ["JavaScript", "C", "Java"] },
{ id: 2, name: "Antonio Villena", memberSince: "2014-08-15", favoriteLanguageProgramming: ["Go", "Python", "JavaScript"] },
{ id: 3, name: "Jesús Segado", memberSice: "2015-03-15", favoriteLanguageProgramming: ["PHP", "JAVA", "JavaScript"] },
];
const users = [{ id: 1, name: "Carlos Caballero", memberSince: "1997-04-20", favoriteLanguageProgramming: ["JavaScript", "C", "Java"] }, { id: 2, name: "Antonio Villena", memberSince: "2014-08-15", favoriteLanguageProgramming: ["Go", "Python", "JavaScript"] }, { id: 3, name: "Jesús Segado", memberSice: "2015-03-15", favoriteLanguageProgramming: ["PHP", "JAVA", "JavaScript"] } ];
const benutzer = {
id: 1,
name: "John Smith",
mitgliedVon: "1997-04-20",
};
Gehaltserhöhung(benutzer, 1000);
const użytkownik = {
id: 1,
imię: "John Smith",
członekZ: "1997-04-20",
};
wzrostWynagrodzeń(benutzer, 1000);
const user = {
id: 1,
name: "John Smith",
memberSince: "1997-04-20",
};
increaseSalary(user, 1000);
root = true
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,py}]
charset = utf-8
[*.py]
indent_style = space
indent_size = 4
[Makefile]
indent_style = tab
[*.js]
indent_style = space
indent_size = 2
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
{
"globals": {
"myModule": true
},
"env": {
"browser": true
},
"rules": {
"no-unused-vars": "error",
"quotes": ["warning", "double"]
}
}
const a = 'a';
const b = a;
const c = b;
const d;
const d; // elapsed time in days
const elapseTimeInDays;
Use pronounceable names
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
}
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;
}
const aCountries = []
const sName = ''
const dAmount = 3.2;
Use the same vocabulary for the same type of variable
getUserInfo();
getClientData();
getCustomerRecord();
getUser();
const Car = {
carMake: 'Honda',
carModel: 'Accord',
carColor: 'Blue'
};
function paintCar(car) {
car.carColor = 'Red';
}
const Car = {
make: 'Honda',
model: 'Accord',
color: 'Blue'
};
function paint(car) {
car.color = 'Red';
}
// What the heck is 86400000 for?
setTimeout(blastOff, 86400000);
user.rol = "Administrator";
const MILLISECONDS_IN_A_DAY = 86400000;
const ADMINISTRATOR_ROL = "Administrator";
setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
user.rol = ADMINISTRATOR_ROL;
function setName(name) {
const newName = name || 'Juan Palomo';
}
function setName(name = 'Juan Palomo') {
// ...
}
function newBurger(name, price, ingredients, vegan) {
// ...
}
function newBurger({ name, price, ingredients, vegan }) {
// ...
}
newBurger({
name: 'Chicken',
price: 1.25,
ingredients: ['chicken'],
vegan: false,
});
let fruits = 'Banana Apple';
function splitFruits() {
fruits = fruits.split(' ');
}
splitFruits();
console.log(fruits); // ['Banana', 'Apple'];
function splitFruits(fruits) {
return fruits.split(' ');
}
const fruits = 'Banana Apple';
const newFruits = splitFruits(fruits);
console.log(fruits); // 'Banana Apple';
console.log(newFruits); // ['Banana', 'Apple'];
const addItemToCart = (cart, item) => {
cart.push({ item, date: Date.now() });
};
const addItemToCart = (cart, item) => {
return [...cart, {
item,
date: Date.now(),
}];
};
function emailCustomers(customers) {
customers.forEach((customer) => {
const customerRecord = database.find(customer);
if (customerRecord.isActive()) {
email(client);
}
});
}
function emailActiveCustomers(customers) {
customers
.filter(isActiveCustomer)
.forEach(email);
}
function isActiveCustomer(customer) {
const customerRecord = database.find(customer);
return customerRecord.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...
});
}
const REGEXES = [ // ...];
function tokenize(code) {
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;
}
function parseBetterJSAlternative(code) {
const tokens = tokenize(code);
const ast = lexer(tokens);
ast.forEach((node) => // parse...);
}
const items = [{
name: 'Coffe',
price: 500
}, {
name: 'Ham',
price: 1500
}, {
name: 'Bread',
price: 150
}, {
name: 'Donuts',
price: 1000
}
];
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price;
}
const items = [{
name: 'Coffe',
price: 500
}, {
name: 'Ham',
price: 1500
}, {
name: 'Bread',
price: 150
}, {
name: 'Donuts',
price: 1000
}
];
const total = items
.map(output => output.price)
.reduce((total, price) => total + price);
class Car {
constructor({ make, model, color } = car) {
/* */
}
setMake(make) {
this.make = make;
}
setModel(model) {
this.model = model;
}
setColor(color) {
this.color = color;
}
save() {
console.log(this.make, this.model, this.color);
}
}
const car = new Car('WV','Jetta','gray');
car.setColor('red');
car.save();
class Car {
constructor({ make, model, color } = car){}
setMake(make) {
this.make = make;
return this;
}
setModel(model) {
this.model = model;
return this;
}
setColor(color) {
this.color = color;
return this;
}
save() {
console.log(this.make, this.model, this.color);
return this;
}
}
const car = new Car('WV','Jetta','gray')
.setColor('red')
.save();
try {
functionThatMightThrow();
} catch (error) {
console.log(error);
}
try {
functionThatMightThrow();
} catch (error) {
console.error(error);
notifyUserOfError(error);
reportErrorToService(error);
}
getdata()
.then((data) => functionThatMightThrow(data))
.catch((error) => {
console.log(error);
});
getdata()
.then((data) => functionThatMightThrow(data))
.catch((error) => {
console.error(error);
notifyUserOfError(error);
reportErrorToService(error);
});
function emailCustomers(customers) {
customers.forEach((customer) => {
const customerRecord = database.find(customer);
if (customerRecord.isActive()) {
email(client);
}
});
}
function emailActiveCustomers(customers) {
customers
.filter(isActiveCustomer)
.forEach(email);
}
function isActiveCustomer(customer) {
const customerRecord = database.find(customer);
return customerRecord.isActive();
}
export class UserException extends Error {
constructor(message) {
super(`User: ${message}`);
}
}
export class AdminException extends Error {
constructor(message) {
super(`Admin: ${message}`);
}
}
//...
const id = 1;
const user = this.users.find({id});
if(user){
throw new UserException("This user already exists");
}
function book(customer, isPremium) {
// ...
if(isPremium){
premiumLogic();
}else{
regularLogic();
}
}
function bookPremium (customer){
premiumLogic();
}
function bookRegular (customer){
regularLogic();
}
if (platform.state === 'fetching' && isEmpty(cart)) {
// ...
}
function showLoading(platform, cart) {
return platform.state === 'fetching' && isEmpty(cart);
}
if (showLoading(platform, cart)) {
// ...
}
function getPayAmount() {
let result;
if (isDead){
result = deadAmount();
}else {
if (isSeparated){
result = separatedAmount();
} else {
if (isRetired){
result = retiredAmount();
}else{
result = normalPayAmount();
}
}
}
return result;
}
function getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
}
function Auto() {
}
Auto.prototype.getProperty = function () {
switch (type) {
case BIKE:
return getBaseProperty();
case CAR:
return getBaseProperty() - getLoadFactor();
case BUS:
return (isNailed) ?
0 :
getBaseProperty(voltage);
}
throw new Exception("Should be unreachable");
};
TypeScript
abstract class Auto {
abstract getProperty();
}
class Bike extends Auto {
getProperty() {
return getBaseProperty();
}
}
class Car extends Auto {
getProperty() {
return getBaseProperty() - getLoadFactor();
}
}
class Bus extends Auto {
getProperty() {
return (isNailed) ?
0 :
getBaseProperty(voltage);
}
}
// Somewhere in client code
speed = auto.getProperty();
function logMessage(message = "CRITICAL::The system ..."){
const parts = message.split("::");
const level = parts[0];
switch (level) {
case 'NOTICE':
console.log("Notice")
break;
case 'CRITICAL':
console.log("Critical");
break;
case 'CATASTROPHE':
console.log("Castastrophe");
break;
}
}
const strategies = {
criticalStrategy,
noticeStrategy,
catastropheStrategy,
}
function logMessage(message = "CRITICAL::The system ...") {
const [level, messageLog] = message.split("::");
const strategy = `${level.toLowerCase()}Strategy`;
const output = strategies[strategy](messageLog);
}
function criticalStrategy(param) {
console.log("Critical: " + param);
}
function noticeStrategy(param) {
console.log("Notice: " + param);
}
function catastropheStrategy(param) {
console.log("Catastrophe: " + param);
}
logMessage();
logMessage("CATASTROPHE:: A big Catastrophe");
import { get } from 'request';
import { writeFile } from 'fs';
get(API_ENDPOINT,
(requestErr, response) => {
if (requestErr) {
console.error(requestErr);
} else {
writeFile(MY_FILE, response.body,
(writeErr) => {
if (writeErr) {
console.error(writeErr);
} else {
console.log('File written');
}
});
}
});
import { get } from 'request';
import { writeFile } from 'fs';
get(API_ENDPOINT)
.then((response) => {
return writeFile(MY_FILE, response);
})
.then(() => {
console.log('File written');
})
.catch((err) => {
console.error(err);
});
import { get } from 'request';
import { writeFile } from 'fs';
get(API_ENDPOINT)
.then((response) => {
return writeFile(MY_FILE, response);
})
.then(() => {
console.log('File written');
})
.catch((err) => {
console.error(err);
});
import { get } from 'request-promise';
import { writeFile } from 'fs-promise';
async function asyncFunction() {
try {
const response = await get(API_ENDPOING);
await writeFile(MY_FILE, response);
console.log('File written');
} catch(err) {
console.error(err);
}
}
const math = require('../src/math');
describe("math module:", () => {
describe("#sum", function(){
it("should be 0 when the array is empty", () => {
expect(math.sum([])).toBe(0);
});
it("should be x when the array contains an unique value x", function(){
const data = [
[[0], 0],
[[1], 1],
[[999], 999]
];
data.forEach(function(test) {
expect(math.sum(test[0])).toBe(test[1]);
});
});
});
});
it("should be the sum of each element of the array", () => {
const data = [
[[1, 2], 3],
[[1, 2, 3], 6],
[[1, 2, 3, 4], 10]
];
data.forEach(function(test) {
expect(math.sum(test[0])).toBe(test[1]);
});
});
describe("should return an exception", () => {
it("when the array is null", () => {});
})
});
});