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.

Related essays

Next essay
TypeScript Generics: Complete Guide to Flexible Types