Skip to content
All essays
CraftFebruary 10, 20259 min

Clean Code: Writing Maintainable Software

Learn clean code principles. Write maintainable, readable, and robust software.

Ü
Ümit Uz
Mobile & Full Stack Developer

Naming

javascript
// Bad
const d = new Date();

// Good
const currentDate = new Date();

// Bad
function getUser(u) { return u.name; }

// Good
function getUserName(user) { return user.name; }

Functions

javascript
// Bad: Too long, does too much
function processUser(userData) {
  // 50 lines of validation
  // 30 lines of transformation
  // 40 lines of database save
  // 20 lines of email sending
}

// Good: Single responsibility
function validateUser(userData) { /* ... */ }
function transformUser(userData) { /* ... */ }
function saveUser(user) { /* ... */ }
function sendWelcomeEmail(user) { /* ... */ }

async function registerUser(userData) {
  const validated = validateUser(userData);
  const transformed = transformUser(validated);
  const user = await saveUser(transformed);
  await sendWelcomeEmail(user);
  return user;
}

Comments

javascript
// Bad: Comment explains what
// Check if user is logged in
if (user.isLoggedIn) { /* ... */ }

// Good: Code is self-explanatory
if (user.isLoggedIn) { /* ... */ }

// Bad: Obvious comment
// Increment counter
count++;

// Good: Comment explains WHY
// Using setTimeout to avoid race condition in event loop
setTimeout(() => processNext(), 0);

DRY (Don't Repeat Yourself)

javascript
// Bad: Duplicated logic
function calculateAreaCircle(radius) {
  return Math.PI * radius * radius;
}

function calculateCircumferenceCircle(radius) {
  return 2 * Math.PI * radius;
}

// Good: Extract common logic
const circleMath = {
  area: (r) => Math.PI * r * r,
  circumference: (r) => 2 * Math.PI * r
};

Error Handling

javascript
// Bad: Silent failures
function parseJSON(str) {
  try {
    return JSON.parse(str);
  } catch (e) {
    return null;
  }
}

// Good: Handle errors appropriately
function parseJSON(str, defaultValue = null) {
  try {
    return JSON.parse(str);
  } catch (e) {
    logger.error('JSON parse failed', { error: e.message, input: str });
    return defaultValue;
  }
}

Code Smells

  1. 1Long functions: Break down into smaller functions
  2. 2Duplicated code: Extract to functions/variables
  3. 3Large parameter lists: Use objects
  4. 4Feature envy: Function uses more of other objects
  5. 5Shotgun surgery: Changes require many small changes

Refactoring

javascript
// Before: Nested conditionals
function processOrder(order) {
  if (order) {
    if (order.items) {
      if (order.items.length > 0) {
        // Process order
      }
    }
  }
}

// After: Early returns
function processOrder(order) {
  if (!order) return;
  if (!order.items) return;
  if (order.items.length === 0) return;

  // Process order
}

Clean code is not about following rules blindly, but about writing code that others (and future you) can understand and modify.

Enjoyed this essay? Share it.

Related essays

Next essay
TypeScript Generics: Complete Guide to Flexible Types