DEV Community

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

Posted on

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

Top comments (0)