」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 單一責任原則

單一責任原則

發佈於2024-11-09
瀏覽:255

Single Responsibility Principle

每個軟體元件應該只有一個且一個職責

軟體元件可以是類別、方法或模組

例如,瑞士軍刀是一種多用途工具,違反了軟體開發的單一責任原則,相反,刀是遵循單一責任的一個很好的例子(因為與瑞士軍刀不同,它只能用於切割可用於切割、打開罐頭、作為萬能鑰匙、剪刀等)

由於無論是現實世界或軟體開發,變化都是不變的,單一職責原則的定義也會隨之改變

每個軟體元件都應該有且只有一個更改的理由


下面的 Employee 類別中可能發生變化的原因有 3 個原因

  1. 員工屬性變化
  2. 資料庫更改
  3. 稅金計算的變化
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

/**
 * Employee class has details of employee
 * This class is responsible for saving employee details, getting tax of
 * employee and getting
 * details of employee like name, id, address, contact, etc.
 */
public class Employee {
    private String employeeId;
    private String employeeName;
    private String employeeAddress;
    private String contactNumber;
    private String employeeType;

    public void save() {
        String insert = MyUtil.serializeIntoString(this);
        Connection connection = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc://mysql://localhost:8080/MyDb", "root", "password");
            statement = connection.createStatement();
            statement.execute("insert into employee values ("   insert   ")");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void calculateTax() {
        if (this.getEmployeeType().equals("fulltime")) {
            // tax calculation for full time employee
        } else if (this.getEmployeeType().equals("contract")) {
            // tax calculation for contract type employee
        }
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public String getEmployeeAddress() {
        return employeeAddress;
    }

    public void setEmployeeAddress(String employeeAddress) {
        this.employeeAddress = employeeAddress;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmployeeType() {
        return employeeType;
    }

    public void setEmployeeType(String employeeType) {
        this.employeeType = employeeType;
    }

}

由於SRP(單一職責原則)建議類別中只有一個更改原因,我們將不得不在Employee類別中進行一些修改


SRP 變化

現在,只有一個原因可以導致 Employee 類別發生變化

變更原因:員工屬性變更

/**
 * Employee class has details of employee
 */
public class Employee {
    private String employeeId;
    private String employeeName;
    private String employeeAddress;
    private String contactNumber;
    private String employeeType;

    public void save() {
       new EmployeeRepository().save(this);
    }

    public void calculateTax() {
       new TaxCalculator().calculateTax(this);
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public String getEmployeeAddress() {
        return employeeAddress;
    }

    public void setEmployeeAddress(String employeeAddress) {
        this.employeeAddress = employeeAddress;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmployeeType() {
        return employeeType;
    }

    public void setEmployeeType(String employeeType) {
        this.employeeType = employeeType;
    }

}

此外,EmployeeRepository 類別中發生變更的原因只有一個

更改原因:資料庫變更

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class EmployeeRepository {

    public void save(Employee employee) {
         String insert = MyUtil.serializeIntoString(employee);
        Connection connection = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc://mysql://localhost:8080/MyDb", "root", "password");
            statement = connection.createStatement();
            statement.execute("insert into employee values ("   insert   ")");

        } catch (Exception e) {
            e.printStackTrace();
        }
}

}

最後,TaxCalculator 類別中發生變化的原因只有一個

變更原因:稅務計算變更

public class TaxCalculator {

    public void calculateTax(Employee employee) {
        if (employee.getEmployeeType().equals("fulltime")) {
            // tax calculation for full time employee
        } else if (employee.getEmployeeType().equals("contract")) {
            // tax calculation for contract type employee
        }
    }
}

注意:所有 3 個類別現在都遵循單一職責原則,因此遵循兩個定義

在建立類別或任何軟體元件時請記住:以高內聚和鬆散耦合為目標

每個軟體元件應該只有一個和一個職責
每個軟體元件都應該有且僅有一個更改的理由

版本聲明 本文轉載於:https://dev.to/prashantrmishra/single-responsibility-principle-m8n?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 使用 JavaScript Web 元件和 LIT 建置可重複使用元件
    使用 JavaScript Web 元件和 LIT 建置可重複使用元件
    在當今快節奏的 Web 開發環境中,建立可重複使用和可維護的元件是關鍵。 JavaScript Web 元件 提供了一種原生方法來建立跨框架工作的獨立、模組化元素。然而,手動建立這些組件可能既乏味又複雜。這就是 LIT 發揮作用的地方! LIT 簡化了建立 Web 元件的過程,使管理狀態、反應性和...
    程式設計 發佈於2024-11-09
  • 如何在 C++ 中傳遞給非主函數的陣列上使用基於範圍的 for 迴圈?
    如何在 C++ 中傳遞給非主函數的陣列上使用基於範圍的 for 迴圈?
    傳遞給非主函數的數組上基於範圍的for 循環在C 中,基於範圍的for 循環可以是用於迭代數組。但是,當數組傳遞給非主函數時,它會衰減為指針,從而失去其大小資訊。 要解決此問題並啟用基於範圍的 for 循環,數組應該被引用而不是作為指標傳遞。這保留了數組的大小資訊。以下是示範正確方法的修改範例:vo...
    程式設計 發佈於2024-11-09
  • array_column 與 PHP 中的物件陣列相容嗎?
    array_column 與 PHP 中的物件陣列相容嗎?
    在物件陣列中使用 array_column 是否可行? PHP 的 array_column 函數是從多維資料中提取特定列的強大工具大批。然而,它與物件數組一起使用帶來了挑戰。 在早期版本的 PHP 中,array_column 不支援物件陣列。作為一種解決方法,可以使用 array_map 手動提...
    程式設計 發佈於2024-11-09
  • 何時使用 PDO 而不是 mysql_real_escape_string 來轉義 MySQL 查詢?
    何時使用 PDO 而不是 mysql_real_escape_string 來轉義 MySQL 查詢?
    轉義MySQL 查詢:PDO 與mysql_real_escape_string雖然mysql_real_escape_string 提供了一種轉義MySQL 查詢並防止SQL 注入的方法,但建議使用PHP 資料物件( PDO) )以增強安全性和多功能性。 什麼是PDO? PDO 是 PHP 中物件...
    程式設計 發佈於2024-11-09
  • 如何將`std::string`轉換為`LPCSTR`和`LPWSTR`?
    如何將`std::string`轉換為`LPCSTR`和`LPWSTR`?
    將std::string 轉換為LPCSTR 和LPWSTR將std::string 轉換為LPCSTR 或LPWSTR 需要理解這些的本質指標。讓我們澄清一下它們的定義:LPCSTR 與 LPSTR:LPCSTR:指向常數字串的長指針,本質上是 const char*。 LPSTR:指向字串的長指...
    程式設計 發佈於2024-11-09
  • 黃瓜測試:綜合指南
    黃瓜測試:綜合指南
    Cucumber 是一款支持行为驱动开发 (BDD) 的开源测试工具,使团队能够用任何人都能理解的简单语言编写测试。通过弥合开发人员、测试人员和非技术利益相关者之间的差距,Cucumber 确保软件满足功能和业务需求。 在本文中,我们将深入探讨 Cucumber 测试是什么、它的主要功能以及如何在...
    程式設計 發佈於2024-11-09
  • ## Compare() 與 CompareTo():什麼時候應該在 Java 中使用 Each ?
    ## Compare() 與 CompareTo():什麼時候應該在 Java 中使用 Each ?
    闡明compare()和compareTo()之間的區別Java生態系統圍繞操作對象展開,確定它們的相對順序在各種場景中至關重要。本文旨在闡明兩個關鍵方法:compare() 和compareTo() 之間的細微差別,闡明它們在比較對像中的不同作用。 compareTo()compareTo() 位...
    程式設計 發佈於2024-11-09
  • 兩個指針和滑動視窗模式
    兩個指針和滑動視窗模式
    雙指標與滑動視窗模式 模式1:常數視窗(如window = 4或某個整數值) 例如,給定一個(-ve 和 ve)整數數組,找到大小為 k 的連續視窗的最大和. 模式2:(可變視窗大小)具有的最大子數組/子字串範例:sum
    程式設計 發佈於2024-11-09
  • 何時使用 PSR-4 與類別映射自動載入以獲得最佳效能?
    何時使用 PSR-4 與類別映射自動載入以獲得最佳效能?
    PSR-4 與類別映射自動載入:解決效能爭論問題Composer 為類別自動載入提供了多種選項:PSR- 0/ 4 標準或直接類別映射掃描。儘管文件推薦 PSR-4,但使用者認為類別映射提供更快的載入速度。這就提出了一個問題:如果類別映射看起來比 PSR-4 更優秀,為什麼還要使用 PSR-4? P...
    程式設計 發佈於2024-11-09
  • 使用Java Native Access (JNA)呼叫MacOS API
    使用Java Native Access (JNA)呼叫MacOS API
    介紹 這是一個關於如何將 JNA 與 MacOS API 結合使用的簡單範例。我不會解釋這一點,因為我仍在學習,但我將程式碼保持最少,以便更容易理解並了解如何將其用於其他目的的基本概念。 大部分程式碼來自 Intellij-Community(Apache 授權)。 ...
    程式設計 發佈於2024-11-09
  • 了解 JavaScript 中的匯出和匯入
    了解 JavaScript 中的匯出和匯入
    在 JavaScript 中,模組是獨立的程式碼單元,可以使用匯出將資產公開給其他模組,並使用導入使用來自其他模組的資產。這種機制對於在現代 JavaScript 應用程式中建立模組化和可重複使用的程式碼至關重要。 預設導出 一個模組只能有一個預設導出。 要匯出預設資源,請在匯出的實體之前使用 ...
    程式設計 發佈於2024-11-09
  • 如何避免 Go 模板中 HTML 和 JSON 的意外轉義?
    如何避免 Go 模板中 HTML 和 JSON 的意外轉義?
    在Go 模板中轉義HTML 和JSON在Go 模板中,正確處理HTML 和JSON 以防止意外轉義至關重要。考慮以下範本:<some_html> {{ .SomeOtherHTML }} </some_html>如果您希望輸出只是 ,那麼您可能會遇到到< 和& 等特殊字元被轉...
    程式設計 發佈於2024-11-09
  • CORS 可防止哪些錯誤:「Access-Control-Allow-Origin 不允許來源」?
    CORS 可防止哪些錯誤:「Access-Control-Allow-Origin 不允許來源」?
    CORS 防止的錯誤:「Access-Control-Allow-Origin 不允許來源」簡介:跨來源資源共享(CORS) 期間,當用戶端腳本嘗試從與其運行來源不同的來源存取資源。 原因:此錯誤有幾個潛在原因: 同源策略:未經伺服器明確許可, JavaScript 被限制存取其網域之外的資源。此策...
    程式設計 發佈於2024-11-09
  • 為什麼 useState 在嚴格模式下渲染元件兩次?
    為什麼 useState 在嚴格模式下渲染元件兩次?
    理解useState中的雙重渲染在React中,useState鉤子通常用於管理元件狀態。但是,在某些條件下,您可能會注意到使用 useState 呈現的元件對於每次狀態更新都會呈現兩次。這種行為讓許多未啟用嚴格模式的開發人員感到困惑。為什麼會出現這種情況? 嚴格模式的作用與未啟用嚴格模式的假設相反...
    程式設計 發佈於2024-11-09
  • Flex 專案是區塊級還是 Flex 級?深入研究 CSS 佈局
    Flex 專案是區塊級還是 Flex 級?深入研究 CSS 佈局
    Flex 專案令人困惑的本質:區塊級還是 Flex 等級? Flex 專案是否是區塊級的問題一直是CSS 開發者之間的爭論。 CSS 靈活框佈局模組等級 1 規定 Flex 項目位於 Flex 級別,而不是區塊級別。然而,後面的部分顯示彈性項目的顯示值是「塊化」的。這就提出了一個問題:Flex 專案...
    程式設計 發佈於2024-11-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3