Single-Responsibility Principle (SRP)
A class should have one and only one reason to change, meaning that a class should have only one job.
จาก concept ข้างต้นถ้าจะสรุปให้สั้นก็คือ class นั้นๆ ควรทำแค่หน้าที่เดียว แต่เหตุผลที่จะแก้ ก็ควรมีแค่เหตุผลเดียว มาดูตัวอย่างกัน
❌ Bad
class TodoManager {
func fetchTodos(completion: @escaping ([Todo]?, Error?) -> Void) {
// Fetch TODOs from the network
let url = URL(string: "https://jsonplaceholder.typicode.com/todos")!
URLSession.shared.dataTask(with: url) { data, response, error in
// Handle network response and parse TODOs
// ...
// Notify the completion block
completion(todos, error)
}.resume()
}
func displayTodos(todos: [Todo]) {
// Display TODOs in the user interface
// ...
}
}
จากตัวอย่างข้างบนผมมี class TodoManager
ซึ่งมี method fetchTodos
ที่ทำหน้าที่ดึงข้อมูล และ displayTodos สำหรับแสดงข้อมูล ซึ่งไม่ตรงตามกฎละ เพราะมันทำหน้าที่มากกว่า หนึ่งอย่างทั้งดึงข้อมูลและแสดงข้อมูล ปัญหาที่ตามมาก็คือถ้าเราต้องการจะแก้การดึงข้อมูล อาจจะกระทบไปโดนส่วนการแสดงข้อมูลด้วยก็ได้ วิธีการแก้ปัญหาเราควรที่จะ แยกการแสดงข้อมูลไปอีก class เลย
✅ Good
class TodoNetworkManager {
func fetchTodos(completion: @escaping ([Todo]?, Error?) -> Void) {
// Fetch TODOs from the network
let url = URL(string: "https://jsonplaceholder.typicode.com/todos")!
URLSession.shared.dataTask(with: url) { data, response, error in
// Handle network response and parse TODOs
// ...
// Notify the completion block
completion(todos, error)
}.resume()
}
}
class TodoUIManager {
func displayTodos(todos: [Todo]) {
// Display TODOs in the user interface
// ...
}
}
ทีนี้ถ้าเราอยากแก้การดึงข้อมูลหรือการแสดงผลก็จะไม่ไปยุ่งกับอีก class ละ ก็จะช่วยลดความผิดพลาดในการมาแก้ไขในครั้งถัดไป แล้วง่ายต่อการอ่านและการ maintain ด้วย