DEV Community

Cover image for KISS Principle (Keep It Simple, Stupid)
Parzival
Parzival

Posted on

1

KISS Principle (Keep It Simple, Stupid)

Understanding KISS

KISS advocates for simplicity in software design. Complex systems are more prone to errors, harder to maintain, and difficult for other developers to understand.

Real-World Examples

1. Data Retrieval

// Complex (Bad)
class UserRepository {
    public function getUserWithDetails($userId) {
        return array_reduce(
            $this->db->query("SELECT * FROM users WHERE id = ?", [$userId])->fetch(),
            function($carry, $userData) {
                return array_merge(
                    $carry,
                    $this->enrichUserData(
                        $userData,
                        $this->getAdditionalData($userData['id'])
                    )
                );
            },
            []
        );
    }

    private function enrichUserData($userData, $additionalData) {
        return array_map(
            function($data) use ($userData) {
                return $this->transformData($data, $userData);
            },
            $additionalData
        );
    }
}

// Simple (Good)
class UserRepository {
    public function getUserWithDetails($userId) {
        $user = $this->db->query("SELECT * FROM users WHERE id = ?", [$userId])->fetch();
        if (!$user) {
            return null;
        }

        $user['address'] = $this->getAddress($userId);
        $user['orders'] = $this->getRecentOrders($userId);

        return $user;
    }

    private function getAddress($userId) {
        return $this->db->query("SELECT * FROM addresses WHERE user_id = ?", [$userId])->fetch();
    }

    private function getRecentOrders($userId) {
        return $this->db->query(
            "SELECT * FROM orders WHERE user_id = ? ORDER BY created_at DESC LIMIT 5",
            [$userId]
        )->fetchAll();
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Configuration Management

// Complex (Bad)
class ConfigManager {
    private $config = [];

    public function get($key) {
        return array_reduce(
            explode('.', $key),
            function($carry, $segment) {
                return is_array($carry) && isset($carry[$segment]) 
                    ? $carry[$segment] 
                    : null;
            },
            $this->config
        );
    }

    public function set($key, $value) {
        $segments = explode('.', $key);
        $current = &$this->config;

        while (count($segments) > 1) {
            $segment = array_shift($segments);
            if (!isset($current[$segment]) || !is_array($current[$segment])) {
                $current[$segment] = [];
            }
            $current = &$current[$segment];
        }

        $current[array_shift($segments)] = $value;
    }
}

// Simple (Good)
class ConfigManager {
    private $config = [];

    public function get($key) {
        if (isset($this->config[$key])) {
            return $this->config[$key];
        }
        return null;
    }

    public function set($key, $value) {
        $this->config[$key] = $value;
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Date Handling

// Complex (Bad)
function getNextBusinessDay($date) {
    $timestamp = strtotime($date);
    $daysToAdd = 1;

    while (true) {
        $nextDay = strtotime("+$daysToAdd days", $timestamp);
        $dayOfWeek = date('N', $nextDay);

        if ($dayOfWeek < 6) {
            $holidays = $this->getHolidays();
            $dateString = date('Y-m-d', $nextDay);

            if (!in_array($dateString, $holidays)) {
                return $dateString;
            }
        }
        $daysToAdd++;
    }
}

// Simple (Good)
function getNextBusinessDay($date) {
    $nextDay = new DateTime($date);
    $nextDay->modify('+1 day');

    while ($this->isWeekendOrHoliday($nextDay)) {
        $nextDay->modify('+1 day');
    }

    return $nextDay->format('Y-m-d');
}

private function isWeekendOrHoliday(DateTime $date) {
    $dayOfWeek = $date->format('N');
    $isWeekend = ($dayOfWeek >= 6);
    $isHoliday = in_array($date->format('Y-m-d'), $this->holidays);

    return $isWeekend || $isHoliday;
}
Enter fullscreen mode Exit fullscreen mode

4. Form Validation

// Complex (Bad)
function validateUserInput($data) {
    return (
        isset($data['email']) && 
        filter_var($data['email'], FILTER_VALIDATE_EMAIL) &&
        isset($data['password']) && 
        strlen($data['password']) >= 8 &&
        preg_match('/[A-Z]/', $data['password']) &&
        preg_match('/[a-z]/', $data['password']) &&
        preg_match('/[0-9]/', $data['password']) &&
        (!isset($data['phone']) || 
            (preg_match('/^\+?[1-9]\d{1,14}$/', $data['phone']))
        )
    ) ? true : false;
}

// Simple (Good)
class UserValidator {
    public function validate($data) {
        $errors = [];

        if (!$this->isValidEmail($data['email'])) {
            $errors['email'] = 'Invalid email address';
        }

        if (!$this->isValidPassword($data['password'])) {
            $errors['password'] = 'Password must be at least 8 characters with mixed case and numbers';
        }

        if (isset($data['phone']) && !$this->isValidPhone($data['phone'])) {
            $errors['phone'] = 'Invalid phone number';
        }

        return empty($errors) ? true : $errors;
    }

    private function isValidEmail($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }

    private function isValidPassword($password) {
        if (strlen($password) < 8) {
            return false;
        }

        return preg_match('/[A-Z]/', $password) 
            && preg_match('/[a-z]/', $password) 
            && preg_match('/[0-9]/', $password);
    }

    private function isValidPhone($phone) {
        return preg_match('/^\+?[1-9]\d{1,14}$/', $phone);
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Method Length: Keep methods under 20 lines
  2. Single Responsibility: Each class/method should do one thing well
  3. Meaningful Names: Use clear, descriptive names for variables and functions
  4. Avoid Nesting: Limit conditional nesting to 2-3 levels maximum
  5. Early Returns: Return early to avoid deep nesting
  6. Comments: Good code should be self-documenting

Benefits of KISS

  1. Maintainability: Easier to update and modify
  2. Debugging: Simpler to find and fix issues
  3. Onboarding: New team members understand code faster
  4. Testing: Simpler code is easier to test
  5. Performance: Often performs better than complex alternatives

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay