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();
}
}
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;
}
}
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;
}
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);
}
}
Best Practices
- Method Length: Keep methods under 20 lines
- Single Responsibility: Each class/method should do one thing well
- Meaningful Names: Use clear, descriptive names for variables and functions
- Avoid Nesting: Limit conditional nesting to 2-3 levels maximum
- Early Returns: Return early to avoid deep nesting
- Comments: Good code should be self-documenting
Benefits of KISS
- Maintainability: Easier to update and modify
- Debugging: Simpler to find and fix issues
- Onboarding: New team members understand code faster
- Testing: Simpler code is easier to test
- Performance: Often performs better than complex alternatives
Top comments (0)