Scattered Instantiation
Descriptionβ
What does it look like?β
- Classes are instantiated using
new
directly and repeatedly throughout the codebase - Hard to track which classes are used where, leading to unclear dependencies
- Instantiation logic is scattered, making management difficult
Why is it a problem?β
- Results in a fragile design that is hard to modify or replace with new implementations
- Difficult to unit test (hard to inject mocks)
- Object creation logic is often copy-pasted in multiple places
- Instance management becomes tangled like spaghetti code
Bad Example of the Anti-patternβ
- TypeScript
- PHP
- Python
class Logger {
log(message: string) {
console.log(`[LOG]: ${message}`);
}
}
class UserService {
private logger: Logger;
constructor() {
this.logger = new Logger(); // ζ―ε new!!
}
createUser(name: string) {
this.logger.log(`γ¦γΌγΆγΌδ½ζ: ${name}`);
}
}
<?php
class Logger {
public function log(string $message): void {
echo "[LOG]: {$message}\n";
}
}
class UserService {
private Logger $logger;
public function __construct() {
$this->logger = new Logger(); // ζ―ε new!!
}
public function createUser(string $name): void {
$this->logger->log("γ¦γΌγΆγΌδ½ζ: {$name}");
}
}
class Logger:
def log(self, message: str):
print(f"[LOG]: {message}")
class UserService:
def __init__(self):
self.logger = Logger() # ζ―ε new!!
def create_user(self, name: str):
self.logger.log(f"γ¦γΌγΆγΌδ½ζ: {name}")
Issues:β
Logger
is instantiated directly insideUserService
- Other services may also repeat
new Logger()
, leading to duplication - Difficult to reuse the logger logic as a shared component
Refactoring by Patternβ
Design patterns that can address thisβ
Pattern | Overview | Main Refactoring Approach |
---|---|---|
Factory Method | Delegate object creation to a subclass | Make instantiation logic extensible |
Abstract Factory | Group related objects into a factory | Abstract creation logic for easy switching |
Builder | Clarify complex creation steps | Separate construction steps for clarity |
Singleton | Restrict to a single instance and reuse it | Useful for shared global state |