Core Principle
Only implement features when you actually need them, not when you think you might need them in the future.
Examples
Premature Abstraction (Bad)
// Over-engineered solution anticipating future needs
class UserService {
private $database;
private $cache;
private $logger;
private $notifications;
private $analytics;
public function __construct(
DatabaseInterface $database,
CacheInterface $cache,
LoggerInterface $logger,
NotificationService $notifications,
AnalyticsService $analytics
) {
$this->database = $database;
$this->cache = $cache;
$this->logger = $logger;
$this->notifications = $notifications;
$this->analytics = $analytics;
}
public function createUser($data) {
$this->logger->info('Creating user');
$user = $this->database->insert('users', $data);
$this->cache->set('user_' . $user->id, $user);
$this->notifications->sendWelcomeEmail($user);
$this->analytics->trackUserCreation($user);
return $user;
}
}
Simple Implementation (Good)
class UserService {
private $database;
public function __construct(DatabaseInterface $database) {
$this->database = $database;
}
public function createUser($data) {
return $this->database->insert('users', $data);
}
}
Real-World Scenarios
E-commerce Example
// Bad: Implementing unused features
class Product {
private $name;
private $price;
private $stock;
private $weight; // Not needed yet
private $dimensions; // Not needed yet
private $shippingZones; // Not needed yet
private $taxCategories; // Not needed yet
private $customFields; // Not needed yet
public function calculateShipping($address) {
// Complex shipping calculation that isn't required
}
public function calculateTax($country) {
// Complex tax calculation that isn't required
}
}
// Good: Implementing what's needed now
class Product {
private $name;
private $price;
private $stock;
public function __construct(string $name, float $price, int $stock) {
$this->name = $name;
$this->price = $price;
$this->stock = $stock;
}
}
Common Anti-Patterns
- Building complex configuration systems before needed
- Creating elaborate inheritance hierarchies for future extensibility
- Adding database fields for potential future features
- Implementing unneeded API endpoints
- Creating generic solutions for specific problems
Benefits
- Reduced codebase complexity
- Lower maintenance cost
- Faster development cycles
- Better focus on current requirements
- Less technical debt
Exception Cases
- Core architecture decisions
- Data structures that are expensive to change later
- Security considerations
- Regulatory compliance requirements
Top comments (0)