SOLID: Open-Closed Principle

Programming

SOLID: Open-Closed Principle

ไม่ควรยุ่งกับ class เดิม หากอยากได้ความสามารถเพิ่มให้ใช้การ extend

10 เดือนที่ผ่านมา

2 min read

Table of Contents

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")

Tags:

Swift SOLID