Open-Closed Principle (OCP)
Objects or entities should be open for extension but closed for modification.
class ควรเปิดเพื่อขยาย แต่ปิดเพื่อแก้ไข
ซึ่งหมายความว่าเราควรจะสามารถเพิ่มฟังก์ชันการทำงานใหม่ให้กับคลาสได้โดยไม่ต้องแก้ไขโค้ดที่มีอยู่ สรุปสั้นๆ ง่าย ห้ามแก้ class เดิมเพื่อเพิ่มความสามารถให้กับ class
❌ Bad
// Non-compliant class violating the Open-Closed Principle
class AudioFileReader {
func readMp3(file: String) -> String {
return "Reading MP3 file: \(file)"
}
func readWav(file: String) -> String {
return "Reading WAV file: \(file)"
}
}
// Client code violating the Open-Closed Principle
class AudioFileProcessor {
func processAudio(fileReader: AudioFileReader, file: String) {
// The client code needs to know about specific methods for each file format
if file.hasSuffix(".mp3") {
let result = fileReader.readMp3(file: file)
print(result)
} else if file.hasSuffix(".wav") {
let result = fileReader.readWav(file: file)
print(result)
}
// Adding support for a new file format would require modifying this code
}
}
// Example usage (client code violating OCP)
let audioReader = AudioFileReader()
let processor = AudioFileProcessor()
processor.processAudio(fileReader: audioReader, file: "example.mp3")
processor.processAudio(fileReader: audioReader, file: "example.wav")
✅ Good
// Protocol defining the behavior of an audio file reader
protocol AudioFileReader {
func read(file: String) -> String
}
// Concrete implementation for reading MP3 files
class Mp3FileReader: AudioFileReader {
func read(file: String) -> String {
return "Reading MP3 file: \(file)"
}
}
// Concrete implementation for reading WAV files
class WavFileReader: AudioFileReader {
func read(file: String) -> String {
return "Reading WAV file: \(file)"
}
}
// Client code that uses the AudioFileReader without modification
class AudioFileProcessor {
func processAudio(fileReader: AudioFileReader, file: String) {
let result = fileReader.read(file: file)
print(result)
// Additional processing logic can be added here without modifying existing code
}
}
// Example usage
let mp3Reader = Mp3FileReader()
let wavReader = WavFileReader()
let processor = AudioFileProcessor()
processor.processAudio(fileReader: mp3Reader, file: "example.mp3")
processor.processAudio(fileReader: wavReader, file: "example.wav")