Functions should do one thing

Learn about the principle of writing functions that do one thing in this comprehensive guide. Discover the pros and cons, explore bad and good code examples, and uncover related principles for a clean codebase. 🌟


Usage

πŸ“ Guideline

Functions should do one thing: Create a function for each action or concept. Functions should do one and only one thing.

A function in clean code should have a clear purpose and perform a single task. It should not be responsible for multiple actions or concepts. By following this principle, your code becomes more modular, readable, and maintainable.

πŸ› οΈ How to apply

  • Each function should have a clear and specific purpose, focusing on a single task. 🎯
  • Avoid including multiple functionalities or responsibilities within a single function. 🚫
  • Aim to keep your functions concise and easily understandable. πŸ“š
  • Refactor complex functions into smaller, modular ones, each handling a specific task. πŸ”§
  • Avoid functions that need "and," "or," or "if" to indicate multiple tasks or conditions. β›”

Pros and Cons

πŸ‘ Pros

  • Improved code organization: By adhering to this principle, your codebase becomes more structured and easier to navigate. πŸ“‚
  • Enhanced reusability: Well-defined functions that perform a single task can be easily reused in different parts of your application. πŸ”„

πŸ‘Ž Cons

  • Increased function count: Applying this principle may lead to a larger number of functions within your codebase, which could make it more challenging to manage for larger projects. βš™οΈ
  • Potential performance impact: Dividing complex tasks into smaller functions may introduce additional function calls and, in some cases, slightly affect performance. 🐒

Examples

❌ Bad

// Bad: Function performing multiple tasks
function processAnimal(animal: string): void {
    if (animal === 'cat') {
        console.log('Meow!');
        feedCat();
    } else if (animal === 'dog') {
        console.log('Woof!');
        walkDog();
    } else {
        console.log('Unknown animal!');
    }
}
// Bad: Function performing multiple tasks
function processAnimal(animal: string): void {
    if (animal === 'cat') {
        console.log('Meow!');
        feedCat();
    } else if (animal === 'dog') {
        console.log('Woof!');
        walkDog();
    } else {
        console.log('Unknown animal!');
    }
}

βœ… Good

// Good: Functions performing a single task
function makeSound(animal: string): void {
    if (animal === 'cat') {
        console.log('Meow!');
    } else if (animal === 'dog') {
        console.log('Woof!');
    } else {
        console.log('Unknown animal!');
    }
}
 
function feedCat(): void {
    console.log('Feeding the cat...');
}
 
function walkDog(): void {
    console.log('Walking the dog...');
}
// Good: Functions performing a single task
function makeSound(animal: string): void {
    if (animal === 'cat') {
        console.log('Meow!');
    } else if (animal === 'dog') {
        console.log('Woof!');
    } else {
        console.log('Unknown animal!');
    }
}
 
function feedCat(): void {
    console.log('Feeding the cat...');
}
 
function walkDog(): void {
    console.log('Walking the dog...');
}
  • Separation of concerns: Functions should focus on specific tasks, promoting a modular and organized codebase. 🧩
  • Single Responsibility Principle: Each function should have a single responsibility, contributing to maintainable and reusable code. πŸŽ›οΈ
  • KISS (Keep It Simple, Stupid): Strive for simplicity in design and implementation. 🀏