blog / clean-code-prinzipien

5 Clean Code Prinzipien, die ich täglich anwende

Warum Clean Code wichtig ist

Wir schreiben Code nicht nur für Computer, sondern auch für Menschen. Code wird viel häufiger gelesen als geschrieben, deshalb ist Lesbarkeit entscheidend. In diesem Post teile ich 5 Prinzipien, die ich täglich anwende, um meinen Code sauberer zu machen.

1. Aussagekräftige Namen verwenden

Schlecht:

function calc(x, y, z) {
  return x * y * z;
}

const d = new Date();
const t = 86400;

Besser:

function calculateShippingCost(weight, distance, rate) {
  return weight * distance * rate;
}

const currentDate = new Date();
const SECONDS_PER_DAY = 86400;

Warum das wichtig ist:

  • Der Code dokumentiert sich selbst
  • Keine Kommentare nötig, um zu verstehen, was passiert
  • Neue Teammitglieder verstehen den Code sofort

2. Funktionen sollten eine Sache tun

Schlecht:

function processUser(user) {
  // Validierung
  if (!user.email || !user.name) {
    throw new Error('Invalid user');
  }

  // Transformation
  user.email = user.email.toLowerCase();
  user.name = user.name.trim();

  // Speichern in DB
  database.save(user);

  // Email senden
  emailService.sendWelcomeEmail(user.email);

  // Logging
  logger.info(`User ${user.id} processed`);

  return user;
}

Besser:

function processUser(user) {
  const validatedUser = validateUser(user);
  const normalizedUser = normalizeUser(validatedUser);
  const savedUser = saveUser(normalizedUser);

  sendWelcomeEmail(savedUser);
  logUserCreation(savedUser);

  return savedUser;
}

function validateUser(user) {
  if (!user.email || !user.name) {
    throw new Error('Invalid user');
  }
  return user;
}

function normalizeUser(user) {
  return {
    ...user,
    email: user.email.toLowerCase(),
    name: user.name.trim()
  };
}

function saveUser(user) {
  return database.save(user);
}

function sendWelcomeEmail(user) {
  emailService.sendWelcomeEmail(user.email);
}

function logUserCreation(user) {
  logger.info(`User ${user.id} processed`);
}

Vorteile:

  • Jede Funktion ist testbar
  • Wiederverwendbar
  • Einfacher zu debuggen
  • Leichter zu verstehen

3. Vermeide Magic Numbers und Magic Strings

Schlecht:

if (user.status === 1) {
  // Was bedeutet 1?
}

setTimeout(() => {
  retry();
}, 5000); // Warum 5000?

if (user.age > 18) {
  // Hardcoded business logic
}

Besser:

const UserStatus = {
  ACTIVE: 1,
  INACTIVE: 2,
  SUSPENDED: 3
};

const RETRY_DELAY_MS = 5000;
const LEGAL_AGE = 18;

if (user.status === UserStatus.ACTIVE) {
  // Klar, was hier passiert
}

setTimeout(() => {
  retry();
}, RETRY_DELAY_MS);

if (user.age > LEGAL_AGE) {
  //Businesslogik ist dokumentiert
}

Warum:

  • Werte können zentral geändert werden
  • Code ist selbsterklärend
  • Weniger Fehler bei Änderungen

4. Early Returns statt verschachtelte If-Statements

Schlecht:

function processPayment(payment) {
  if (payment) {
    if (payment.amount > 0) {
      if (payment.method === 'credit_card') {
        if (payment.cardNumber) {
          // Eigentliche Logik erst hier
          return chargeCard(payment);
        } else {
          throw new Error('No card number');
        }
      } else {
        throw new Error('Invalid payment method');
      }
    } else {
      throw new Error('Invalid amount');
    }
  } else {
    throw new Error('No payment provided');
  }
}

Besser:

function processPayment(payment) {
  if (!payment) {
    throw new Error('No payment provided');
  }

  if (payment.amount <= 0) {
    throw new Error('Invalid amount');
  }

  if (payment.method !== 'credit_card') {
    throw new Error('Invalid payment method');
  }

  if (!payment.cardNumber) {
    throw new Error('No card number');
  }

  return chargeCard(payment);
}

Vorteile:

  • Weniger Verschachtelung = leichter zu lesen
  • Fehlerbehandlung am Anfang
  • Happy Path ist klar erkennbar

5. DRY - Don’t Repeat Yourself

Schlecht:

// User erstellen
const newUser = {
  id: generateId(),
  createdAt: new Date(),
  updatedAt: new Date(),
  version: 1,
  ...userData
};

// Product erstellen
const newProduct = {
  id: generateId(),
  createdAt: new Date(),
  updatedAt: new Date(),
  version: 1,
  ...productData
};

// Order erstellen
const newOrder = {
  id: generateId(),
  createdAt: new Date(),
  updatedAt: new Date(),
  version: 1,
  ...orderData
};

Besser:

function createEntity(data) {
  return {
    id: generateId(),
    createdAt: new Date(),
    updatedAt: new Date(),
    version: 1,
    ...data
  };
}

const newUser = createEntity(userData);
const newProduct = createEntity(productData);
const newOrder = createEntity(orderData);

Oder noch besser mit TypeScript:

function createEntity<T>(data: T): T & BaseEntity {
  return {
    id: generateId(),
    createdAt: new Date(),
    updatedAt: new Date(),
    version: 1,
    ...data
  };
}

Bonus: Kommentare richtig einsetzen

// ❌ Schlechte Kommentare
// Inkrementiere i
i++;

// Loop über alle Users
users.forEach(user => {
  // ...
});

// ✅ Gute Kommentare
// HACK: Temporärer Workaround für Bug #1234
// TODO: Refactor this when API v2 is available

/**
 * Berechnet den Rabatt basierend auf komplexer Businesslogik:
 * - VIP Kunden: 20%
 * - Bestellwert > 100€: 10%
 * - Beide Bedingungen: 25%
 */
function calculateDiscount(customer, orderValue) {
  // Implementation
}

Fazit

Clean Code ist keine Raketenwissenschaft, sondern gesunder Menschenverstand:

  1. Schreibe für Menschen, nicht für Maschinen
  2. Halte Funktionen klein und fokussiert
  3. Benenne Dinge so, dass Kommentare unnötig werden
  4. Reduziere Komplexität wo möglich
  5. Eliminiere Duplikation

Dein zukünftiges Ich (und deine Kollegen) werden es dir danken! 🚀

Weiterführende Ressourcen


Was sind deine liebsten Clean Code Praktiken? Lass es mich wissen!