Definition:
OCP states: "Software entities (classes, modules, functions) should be open for extension but closed for modification."
- That means:
Open for extension: You can add new behavior without touching the existing code.
Closed for modification: You don't edit existing tested, stable code just to add new features.
- Why this matters:
Prevents breaking existing features.
Improves maintainability.
Reduces regression bugs.
- How to achieve it:
Interfaces / Abstract Classes — define a contract that new implementations follow.
Polymorphism — lets you swap behaviors without changing the base code.
Dependency Injection — avoids hardcoding dependencies.
- Example (Bad OCP):
class ReportGenerator {
public function generate($type) {
if ($type === 'pdf') {
// PDF generation logic
} elseif ($type === 'csv') {
// CSV generation logic
}
}
}
If we want to add Excel, we must edit ReportGenerator — violating OCP.
Better OCP-compliant design:
- We use:
- Interface for report formats.
- Separate classes for each format.
- ReportGenerator doesn't know about specific formats — it just calls the interface.
- Code Example:
interface ReportFormat {
public function generate(array $data): string;
}
class PdfReport implements ReportFormat {
public function generate(array $data): string {
return "PDF Report generated with " . count($data) . " records.";
}
}
class CsvReport implements ReportFormat {
public function generate(array $data): string {
return "CSV Report generated with " . count($data) . " records.";
}
}
class ReportGenerator {
private ReportFormat $format;
public function __construct(ReportFormat $format) {
$this->format = $format;
}
public function generateReport(array $data): string {
return $this->format->generate($data);
}
}
$data = ['name' => 'John', 'age' => 30];
// Generate PDF
$pdfGenerator = new ReportGenerator(new PdfReport());
echo $pdfGenerator->generateReport($data);
// Generate CSV
$csvGenerator = new ReportGenerator(new CsvReport());
echo $csvGenerator->generateReport($data);
Adding a new format (Excel):
class ExcelReport implements ReportFormat {
public function generate(array $data): string {
return "Excel Report generated with " . count($data) . " records.";
}
}
No change to ReportGenerator is needed — OCP respected ✅.
Top comments (0)