Cutting corners will bite you back. Or maybe not, but someone will feel the pain
1. Naming variables with single letters, abbreviations or simply writing cryptic names
I've worked with brilliant developers in the past, people who are able to untangle the most complicated and convoluted scripts. They understand very well the pain of dealing with unreadable code and, despite that, you would find in git pull request code like this.(A made-up example)
// Interface with a bad name 'I'
interface I {
a: string;
b: number;
c: boolean;
}
// Example with Bad Abbreviations
interface Prsn {
nme: string;
ag: number;
isAct: boolean;
}
// Function with bad examples
function dplUsrDtls(usr: Prsn): void {
console.log(`Nme: ${usr.nme}`);
console.log(`Ag: ${usr.ag}`);
console.log(`Is Act: ${usr.isAct}`);
}
OK, the example above is a bit exaggerated, but I am sure that, if you've read code before you've seen examples not too far from that monster above. Most likely you don't like it so don't do it to other people, or to future self.
2. Functions which are doing too much
Every piece of software nowadays should have some sort of "linter" (tools to enforce code style conventions). Most of the linter configurations have some detection for code complexity, could be cyclomatic complexity or cognitive complexity or both. Guess what? Ever so often people decide to disable it for certain files or entirely. What is the point of having that linting rule in first place? Well, good question but people are still doing it. Maybe you rush to finish your day, or you've already overworked, maybe you promise to yourself you will get back to it (most likely it will not happen). But someone will have to pay the price for it eventually.
Ok, let's look at an example.
function processOrder(order) {
// Check if order is valid
if (!order || !order.items || order.items.length === 0) {
console.error("Invalid order: No items provided");
return;
}
let total = 0;
let discount = 0;
let discountApplied = false;
// Calculate total price and apply discounts
for (let item of order.items) {
if (item.quantity < 1) {
console.warn(`Invalid quantity for item ${item.name}`);
continue;
}
total += item.price * item.quantity;
// Apply different discounts based on item type
if (item.type === "electronics" && item.quantity > 2) {
discount += item.price * 0.1; // 10% discount on electronics if more than 2
} else if (item.type === "clothing" && item.price > 100) {
discount += 20; // Flat $20 discount on expensive clothing
} else if (item.type === "groceries") {
discountApplied = true; // No discount but mark as applied
}
}
// Apply discount to the total
if (discount > 0 && !discountApplied) {
total -= discount;
discountApplied = true;
}
// Check for membership discounts
if (order.customer.isMember) {
if (!discountApplied) {
total *= 0.9; // Apply 10% membership discount
} else {
total -= 5; // Apply flat $5 discount for members if another discount already applied
}
}
// Add tax
total *= 1.08; // 8% sales tax
// Check for free shipping eligibility
if (total > 100 || order.customer.isMember) {
console.log("Free shipping applied");
} else {
total += 5; // Add $5 shipping fee
}
// Process payment
if (order.paymentMethod === "credit") {
console.log("Processing credit card payment");
} else if (order.paymentMethod === "paypal") {
console.log("Processing PayPal payment");
} else {
console.error("Unknown payment method");
return;
}
// Final check and output
if (total > 0) {
console.log(`Order processed for ${order.customer.name}. Total amount: $${total.toFixed(2)}`);
} else {
console.error("Total amount is invalid or zero");
}
}
Looks pretty bad and it definitely does too much. Surley you can extra some of the functionality from processOrder to other functions. For example you could have a function to validate orders.
function validateOrder(order) {
if (!order || !order.items || order.items.length === 0) {
console.error("Invalid order: No items provided");
return false;
}
return true;
}
Another function could calculate the total.
// Function to calculate the total price of the order
function calculateTotal(order) {
let total = 0;
for (const item of order.items) {
if (item.quantity < 1) {
console.warn(`Invalid quantity for item ${item.name}`);
continue;
}
total += item.price * item.quantity;
}
return total;
}
Maybe another function to calculate discount.
// Function to apply membership discounts
function applyMembershipDiscount(order, total, discountApplied) {
if (order.customer.isMember) {
if (!discountApplied) {
return total * 0.9; // Apply 10% membership discount
} else {
return total - 5; // Apply flat $5 discount for members if another discount already applied
}
}
return total;
}
You get the gist.
These smaller units of code are easier to read, to debug, to maintain, to reason with. Ideally, when is possible, a function should do one thing. What do you mean by one thing? Your common sense should have the answer.
3. Don't repeat yourself
I know this is a rookie mistake, but you would be surprised how often even the most seasoned developers end up creating 3–4 times the same constant variable. Repeating if/else statements with exactly the same logic in multiple functions. Repeating (copy/paste) entire scripts.
Sometimes repeating is not a bad thing, and sometime is impossible to avoid, but outside of these exceptions, try to do the better thing.
4. Don't leave bad comments behind yourself
I am talking about these 'To Do bla bla bla' comments which nobody will address for years.
When someone else actually wants to do something about it, the comment is so vague and/or old that everyone is scared to touch the logic in order to avoid breaking something. Strive to do the 'To Do' now or keep it for you locally. Don't send it to production on a shared code base.
Even worse, just commented blocks of code, hundreds without any explication. Nobody deserves it.
Final thoughts
I admit. I've been guilty myself of some if not all of these sins at some point.
I am trying to do better and I hope you will too.
We can make our lives easier while enjoying doing what we do.
Thank you for reaching so far, if you don't agree with something or you just want to say hello, drop me a message on linkedin or email.
All the best.