SOLID — จากศูนย์สู่มันฝรั่ง

Mar 29 2023
พวกเราทุกคนคุ้นเคยกับคำหลัก 'SOLID' เป็นอย่างดีในผลงานของเราและคำถามในการสัมภาษณ์ ดังนั้นเราเข้าใจจริง ๆ ว่าอะไรคือ 'SOLID' หากเราต้องการเป็นของแข็งควรรู้เกี่ยวกับ 'SOLID' อย่างลึกซึ้ง 'SOLID' คือการผสมผสานระหว่างหลักการออกแบบ 5 ประการในการพัฒนาซอฟต์แวร์ หลักการเหล่านี้สามารถช่วยคุณในชีวิตประจำวันของคุณได้

พวกเราทุกคนคุ้นเคยกับคำหลัก ' SOLID ' เป็นอย่างดีในผลงานของเราและคำถามในการสัมภาษณ์ ดังนั้นเราเข้าใจจริงๆ เกี่ยวกับ 'SOLID' คืออะไร หากเราต้องการเป็นของแข็งควรรู้เกี่ยวกับ 'SOLID' อย่างลึกซึ้ง

' SOLID ' คือการรวมกันของหลักการออกแบบ 5 ประการในการพัฒนาซอฟต์แวร์ หลักการเหล่านี้สามารถช่วยคุณในชีวิตประจำวันได้ ผมขออธิบายว่า ' SOLID ' ย่อมาจากอะไร:

  1. หลักความรับผิดชอบเดียว (SRP) : ชั้นเรียนควรมีเหตุผลเพียงอย่างเดียวในการเปลี่ยนแปลง
  2. Open/Closed Principle (OCP) : คลาสควรเปิดเพื่อขยาย แต่ปิดเพื่อแก้ไข
  3. Liskov Substitution Principle (LSP) : ชนิดย่อยควรทดแทนได้ด้วยชนิดฐาน
  4. I nterface Segregation Principle (ISP) : ไคลเอนต์ไม่ควรถูกบังคับให้ขึ้นอยู่กับอินเทอร์เฟซที่ไม่ได้ใช้
  5. หลักการผกผันการพึ่งพา (DIP) : โมดูลระดับสูงไม่ควรขึ้นอยู่กับโมดูลระดับต่ำ ทั้งสองควรขึ้นอยู่กับสิ่งที่เป็นนามธรรม

Single Responsibility Principle (SRP) : สมมติว่าเรามีStudentชั้นเรียนที่ไม่เพียงแต่เก็บข้อมูลเกี่ยวกับนักเรียน แต่ยังดำเนินการต่างๆ ที่เกี่ยวข้องกับนักเรียน เช่น คำนวณเกรดเฉลี่ย พิมพ์บัตรรายงาน และส่งอีเมลถึงผู้ปกครอง:

class Student(val name: String, val grades: List<Double>) {
    fun calculateGPA(): Double {
        // calculate the GPA based on the grades
    }

    fun printReportCard() {
        // print the report card for the student
    }

    fun sendEmailToParents() {
        // send an email to the parents of the student
    }
}

ถ้าคุณคิดว่าตัวอย่างด้าน บนไม่เป็นไรและมีปัญหาใดๆ ไม่ต้องกังวลว่าคุณไม่ใช่คนเดียว ฉันก็เคยคิดแบบนั้นมาก่อน ในตัวอย่างนี้ ชั้นเรียนต้องรับผิดชอบStudentงานหลายอย่าง ซึ่งละเมิดหลักการความรับผิดชอบเดี่ยว สิ่งนี้อาจทำให้คลาสยากต่อการบำรุงรักษาและแก้ไขเมื่อเวลาผ่านไป

เพื่อให้เป็นไปตาม SRP เราสามารถแยกความรับผิดชอบของStudentชั้นเรียนได้โดยสร้างชั้นเรียนแยกต่างหากสำหรับแต่ละความรับผิดชอบ ตัวอย่างเช่น เราสามารถสร้างชั้นเรียนGPACalculatorที่รับผิดชอบในการคำนวณเกรดเฉลี่ยของนักเรียน ชั้นReportCardPrinterเรียนที่รับผิดชอบในการพิมพ์รายงาน การ์ดและEmailSenderชั้นเรียนที่รับผิดชอบในการส่งอีเมลถึงผู้ปกครอง:

class Student(val name: String, val grades: List<Double>)

class GPACalculator(val student: Student) {
    fun calculateGPA(): Double {
        // calculate the GPA based on the grades of the student
    }
}

class ReportCardPrinter(val student: Student) {
    fun printReportCard() {
        // print the report card for the student
    }
}

class EmailSender(val student: Student) {
    fun sendEmailToParents() {
        // send an email to the parents of the student
    }
}

แนวทางนี้เป็นไปตามหลักการความรับผิดชอบเดียว เนื่องจากแต่ละชั้นเรียนมีความรับผิดชอบเดียว ทำให้โค้ดง่ายต่อการบำรุงรักษาและแก้ไขเมื่อเวลาผ่านไป นอกจากนี้ การแยกความรับผิดชอบยังช่วยให้มีความยืดหยุ่นมากขึ้นในอนาคต เช่น ความสามารถในการสลับการใช้งานที่แตกต่างกันสำหรับแต่ละความรับผิดชอบตามความจำเป็น

ต่อไปฉันจะอธิบายเกี่ยวกับหลักการอื่นๆ พร้อมตัวอย่างและโดยการ ทำ refactor หวังว่า ตอนนี้คงจะเข้าใจมากขึ้นเกี่ยวกับหลักการความรับผิดชอบเดี่ยว (SRP)