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

S - 單一職責原則(SRP)

發佈於2024-11-06
瀏覽:908

S - Single Responsibility Principle(SRP)

Single Responsibility Principle(SRP)

The Single Responsibility Principle(SRP) is the first of the SOLID principles, which plays an important role in object-oriented programming.

The main point of this principle is: A class or module should have only one responsibility. In other words, a class, module, or function should be used or modified for only one reason.

Detailed Explanation:

  1. Definition of Responsibility:
    Responsibility refers to the specific task or functionality that a class or module performs or manages.

  2. Importance of Single Responsibility:

  • Easy Maintenance: When a class or function has a single responsibility, it's easier to update or modify because the impact of changes is limited.

  • Reusability: Classes or functions with a single responsibility are easier to reuse in other projects or modules.

  • Reduced Complexity: Code complexity is reduced because each class or function has clear and limited tasks.

  • Easy Testing: Small and well-defined classes are easier to test.

For example, let's say we have a class that handles both data processing and file management tasks. This violates the Single Responsibility Principle. In this case, we can create separate classes for data processing and file management. This way, if we need to make changes related to file management in the future, it won't affect the data processing functionality.

Example 1:

Let's say we have a User class that both stores user information and prints that information to the console.

// Java code

public class User {
    private String name;
    private String email;

    // Constructor, Getter, Setter

    public void printUserDetails() {
        System.out.println("Name: "   name);
        System.out.println("Email: "   email);
    }
}

Here, the User class is handling two responsibilities:

  • Storing user information.
  • Printing user information to the console.

According to the Single Responsibility Principle, this class should be divided into two separate classes:

// Java code

// For storing user information
public class User {
    private String name;
    private String email;

    // Constructor, Getter, Setter
}

// For printing user information
public class UserPrinter {
    public void printUserDetails(User user) {
        System.out.println("Name: "   user.getName());
        System.out.println("Email: "   user.getEmail());
    }
}

This way, the responsibility of each class becomes clear and distinct. If we need to change the way information is printed in the future, only the UserPrinter class needs to be modified, while the User class remains unchanged.

Example 2:

Let's say we are building a task management system where a Task class is responsible for creating tasks, updating them, and checking if a task is completed.

// JavaScript code:

class Task {
    constructor(name, completed = false) {
        this.name = name;
        this.completed = completed;
    }
    completeTask() {
        this.completed = true;
    }
    updateTask(name) {
        this.name = name;
    }
    notifyUser() {
        console.log(`Task "${this.name}" is completed!`);
    }
}

const task = new Task('Learn JavaScript');
task.completeTask();
task.notifyUser();

Here, the Task class is handling three different responsibilities:

  • Creating and updating tasks.
  • Completing tasks.
  • Notifying the user when a task is completed.

This violates the Single Responsibility Principle because multiple responsibilities are handled within one class.

Refactoring the code to follow SRP:

Now, we will split these responsibilities into separate classes so that each class has only one responsibility.

// JavaScript code:

// For creating and updating tasks
class Task {
    constructor(name, completed = false) {
        this.name = name;
        this.completed = completed;
    }

    updateTask(name) {
        this.name = name;
    }

    completeTask() {
        this.completed = true;
    }
}

// For notifying the user about task completion
class TaskNotifier {
    notifyUser(task) {
        if (task.completed) {
            console.log(`Task "${task.name}" is completed!`);
        } else {
            console.log(`Task "${task.name}" is not yet completed.`);
        }
    }
}

const task = new Task('Learn JavaScript');
task.completeTask();

const notifier = new TaskNotifier();
notifier.notifyUser(task);

How does this follow the SRP?

  • The Task class is now only responsible for creating and updating tasks. It handles changing the task's name or marking it as completed.

  • The TaskNotifier class is solely responsible for notifying the user about the task's status.

Benefits:

  • If in the future, we need to perform additional actions when a task is completed (e.g., sending an email), only the TaskNotifier class will need to be changed. The Task class remains unchanged.

  • The code is now cleaner, more modular, and easier to maintain.

By following the Single Responsibility Principle, this example shows how breaking the code into smaller, specialized classes can make maintenance easier and improve clarity.

Single Responsibility Principle in React.

Applying the SOLID principles while building a React application can bring significant changes. These principles are fundamental concepts of object-oriented design that provide a strong foundation for writing clean, efficient, and maintainable code. As a result, our React components will not only be functional but also easier to manage and extend.

According to the Single Responsibility Principle (SRP), a class or component should only change for one reason, meaning it should have only one responsibility or task.

How to Apply SRP in React:

To follow the Single Responsibility Principle (SRP) in React:

  • Each Component Should Have a Specific Task or Functionality:
    Each component should serve a single purpose. For example, a component might only display form data, show a user profile, or render a list of items.

  • Keep Components Small and Specialized:
    This makes it easier to test and update each component individually. Smaller, more focused components can be reused across the application, leading to better maintainability and clarity.

By adhering to these guidelines, you can create a more organized and manageable codebase in your React applications.

Example 1:

Let's say we are building a todo application where one component displays a list of tasks, and another component handles the form for adding new tasks.

Good Design According to SRP:

TaskList Component:

function TaskList({ tasks }) {
    return (
        
    {tasks.map(task => (
  • {task.name}
  • ))}
); }
  • This component is responsible solely for displaying the list of tasks.

AddTaskForm Component:

// JavaScript Code:

function AddTaskForm({ onAdd }) {
    const [taskName, setTaskName] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();
        onAdd(taskName);
        setTaskName("");
    };

    return (
        
setTaskName(e.target.value)} placeholder="Add a new task" />
); }
  • This component is solely responsible for managing a form to add new tasks.

Why Following SRP is Beneficial?

  1. Increased Reusability of Components:
    If we want to change only the task list, we can simply update the TaskList component. If we need to modify the form for adding new tasks, we only need to update the AddTaskForm component. This separation makes components more reusable across different parts of the application.

  2. Easier Debugging and Maintenance:
    Instead of handling multiple responsibilities, each component performs a single task. This makes it easier to find and fix bugs, as the scope of potential issues is limited to one component.

  3. Improved Code Understandability for Other Developers:
    Components with clearly defined responsibilities are easier to understand. Smaller, focused components make the codebase more approachable for other developers who might work on the project.

By applying the Single Responsibility Principle (SRP), our React application becomes clearer, more modular, and easier to maintain.

Example 2:

In this example, we have created two separate components: UserProfile and AuthManager, each with a specific task or responsibility.

UserProfile.js:

// JavaScript code

const UserProfile = ({ user }) => (
  

{user.name}

{user.bio}

);

Responsibility of the UserProfile Component:

  • The UserProfile component is solely responsible for displaying the user's profile. It shows the user's name and bio.

AuthManager.js:

// JavaScript code 
const AuthManager = () => (
  
{/* Authentication logic here */} Login Form
);

Responsibility of the AuthManager Component:

  • The AuthManager component is created to handle authentication. It displays the login form and manages the logic required for authentication.

Why This Follows the Single Responsibility Principle (SRP)?

  • Each Component Has a Specific Responsibility:
  • The UserProfile component focuses solely on displaying profile information.

  • The AuthManager component is dedicated to handling authentication logic.

  • Components Are Separate, Manageable, and Testable:
  • If we need to make changes related to displaying profile information, we only need to modify the UserProfile component.

  • Similarly, any updates regarding authentication can be made exclusively within the AuthManager component.

  • Increased Code Reusability:
  • We can reuse the UserProfile and AuthManager components in various parts of our application since they perform specific responsibilities.

By adhering to the Single Responsibility Principle, each component is assigned a single responsibility, which makes the code clean, modular, and easier to maintain.

Disadvantages of the Single Responsibility Principle (SRP)

Disadvantages of the Single Responsibility Principle (SRP)
While the Single Responsibility Principle (SRP) offers numerous advantages, there are also some limitations and challenges that developers may need to consider. Here are some of the key drawbacks:

  1. Increased Number of Components or Classes:
    Following SRP requires creating separate components or classes for each task or responsibility, which can lead to a rapid increase in the number of components or classes in the application. This can make the codebase harder to manage.

  2. Increased Complexity:
    The proliferation of small components or classes can complicate their coordination. Passing data and facilitating communication between various components may become challenging.

  3. Excessive Abstraction:
    Overzealous application of SRP can sometimes result in unnecessary abstraction. Creating too many small components or classes may make the code harder to read and understand, especially if each component's role is trivial.

  4. Learning Curve:
    New developers may find it difficult to fully understand and apply SRP. It requires experience and a clear understanding of how to break down an application into smaller, reusable components.

  5. Overhead in Testing:
    With many small components being created, there is a need to write separate tests for each one. This can increase the time and complexity involved in writing test code.

  6. Balance in Applying SRP:
    It may not always be practical to apply SRP strictly. Sometimes, it can be more effective for a component or class to handle a few closely related responsibilities. Applying SRP excessively can unnecessarily complicate the code, making it more difficult to read and maintain.

By considering these disadvantages, developers can make informed decisions about when and how to apply the Single Responsibility Principle in their projects.

In summary, SRP (Single Responsibility Principle) is a powerful principle that helps keep code clean, modular, and maintainable. However, it should be applied with its limitations in mind. Sometimes, excessive use of the principle can have the opposite effect, so it is important to maintain balance according to the specific needs of the code.

版本聲明 本文轉載於:https://dev.to/nozibul_islam_113b1d5334f/s-single-responsibility-principlesrp-h4g?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • Go ost 量子密碼網路伺服器
    Go ost 量子密碼網路伺服器
    Golang 1.23 將後量子密碼學引入 Go 標準庫。它非常棒且易於使用。 這篇文章「Go 1.23 中的後量子加密 Web 伺服器」包含一些程式碼範例和後量子加密的背景.. 我總是很好奇我正在使用哪個 TLS 密碼套件和曲線,因此我添加了一個片段來執行此操作(使用反射) 您認為還需要更多的例...
    程式設計 發佈於2024-11-06
  • Js電子表格組件
    Js電子表格組件
    我經常使用的一件事是我們用來組織資料的 Excel 表格。 Jspreadsheet 執行的操作非常相似,但直接在瀏覽器中執行。您無需安裝任何東西,只需打開並使用它即可。對於任何需要以簡單實用的方式組織資訊的人來說,它都是完美的選擇。 簡單易用: 如果您曾經使用過 Excel,您會感到賓至如歸。介...
    程式設計 發佈於2024-11-06
  • 掌握 MySQL:每個開發人員都應該監控的關鍵效能指標
    掌握 MySQL:每個開發人員都應該監控的關鍵效能指標
    监控 MySQL 性能指标和管理数据库并不困难。是的,你没听错。有了适当的监控策略和工具,您终于可以退居二线了。 RED 方法与 Releem 强大的监控功能和易于应用的配置建议相结合,可以为您完成繁重的工作。 红色方法简介 RED方法传统上用于监控Web应用程序和服务的性能,但也可...
    程式設計 發佈於2024-11-06
  • 答:C++中如何產生隨機數?
    答:C++中如何產生隨機數?
    這是一個很好的答案! 回覆回覆:如何在C中產生隨機數? 2012 年 11 月 18 日 ...
    程式設計 發佈於2024-11-06
  • 如何在 JavaScript 中對 HTML 實體進行編碼以便在 CMS 中正確顯示?
    如何在 JavaScript 中對 HTML 實體進行編碼以便在 CMS 中正確顯示?
    在JavaScript 中編碼HTML 實體將內容輸入內容管理系統(CMS) 時,處理® 等特殊字元至關重要確保跨瀏覽器正確顯示。為了解決這個問題,可以使用 JavaScript 來定位這些符號並將其轉換為適當的 HTML 實體。 使用正規表示式,可以透過將特定字元範圍替換為對應的 HTML 實體來...
    程式設計 發佈於2024-11-06
  • 為什麼「float: right」會顛倒 HTML 中的 Span 順序?
    為什麼「float: right」會顛倒 HTML 中的 Span 順序?
    Float:跨度的右反轉順序給定 HTML 標記:<div> <span class="label"><a href="/index/1">Bookmix Offline</a></span>...
    程式設計 發佈於2024-11-06
  • Python 字典如何保持程式碼乾淨、乾燥
    Python 字典如何保持程式碼乾淨、乾燥
    Python 字典和 DRY 原则:初学者快速指南 嘿! ?如果您正在深入研究 Python 编程,您可能偶然发现了字典,并且可能想知道“Python 中的字典到底是什么?它如何帮助我更智能地编写代码?”不用担心,让我们用一种超级简单的方式来分解它。 Python ...
    程式設計 發佈於2024-11-06
  • 使用 Django、Twilio 和 Pinata 建立安全的匿名回饋系統
    使用 Django、Twilio 和 Pinata 建立安全的匿名回饋系統
    在本指南中,我将引导您使用 Django、用于短信通知的 Twilio、用于安全媒体上传的 Pinata 以及用于响应式样式的 TailwindCSS 构建安全匿名反馈系统。在本教程结束时,您将拥有一个功能齐全的反馈系统,用户可以在其中提交反馈、选择上传媒体以及接收短信通知 - 所有这些都考虑到安全...
    程式設計 發佈於2024-11-06
  • 為什麼 Tkinter Entry 的 get 函數不回傳任何內容?
    為什麼 Tkinter Entry 的 get 函數不回傳任何內容?
    Tkinter Entry 的get 函數沒有產生任何結果:綜合解釋當嘗試使用get() 從Tkinter Entry 小部件檢索用戶輸入時函數時,您可能會遇到空返回值。這個看似令人困惑的問題源自於 Tkinter 的非同步特性和函數執行的順序。 在提供的程式碼片段中,您嘗試在建立 Entry 後立...
    程式設計 發佈於2024-11-06
  • 使用 NodeJs 開始使用 RabbitMq
    使用 NodeJs 開始使用 RabbitMq
    RabbitMq簡介 RabbitMq 是一個訊息代理,允許在不同服務之間發送和接收訊息。它是一個實作高階訊息佇列協定(AMQP)的訊息代理程式。用 Erlang 程式語言寫成。 安裝 RabbitMq RabbitMq 可以使用各自的套件管理器安裝在不同的作業系統上。 Rabbi...
    程式設計 發佈於2024-11-06
  • 讓網路更加互聯
    讓網路更加互聯
    讓網路更互聯 - Infometka 如何解決「隱形網站」問題 身為 Web 開發人員和 ???️??????️ 的創建者,我一直熱衷於解決現實世界的問題。今天,我想分享我開發的一個解決方案,我相信它可以為無數網站所有者帶來重大改變,並在某種程度上使互聯網成為一個更加互聯的地方。 ...
    程式設計 發佈於2024-11-06
  • 使用 React 建置 Loop Studio
    使用 React 建置 Loop Studio
    介绍 Loop Studio 是一个沉浸式网站,旨在展示各种虚拟现实 (VR) 项目。使用 React,我们可以有效地管理和渲染不同的组件,以构建有凝聚力和交互式的用户体验。该项目采用简洁的设计,带有导航标题、详细的 VR 部分、创作画廊以及带有社交媒体链接的页脚。 ...
    程式設計 發佈於2024-11-06
  • 如何解決用PHP在CURL中傳送多維數組時出現「陣列到字串轉換」錯誤?
    如何解決用PHP在CURL中傳送多維數組時出現「陣列到字串轉換」錯誤?
    透過CURL 和PHP 發送多維數組使用CURL 發布包含多維數組的表單資料時,遇到「數組到字串轉換」錯誤是一個常見問題。當嘗試使用包含陣列的陣列設定 CURLOPT_POSTFIELDS 時會發生這種情況。 由於 Content-Type 標頭必須是 multipart/form-data 以方便...
    程式設計 發佈於2024-11-06
  • 如何在 Selenium 中使用 \"span:contains(\'String\')\" 解決 InvalidSelectorException?
    如何在 Selenium 中使用 \"span:contains(\'String\')\" 解決 InvalidSelectorException?
    Selenium 中的Invalid SelectorException with "span:contains('String')"在Firefox 中使用Python 中的Selenium 時,嘗試使用CSS 選擇器「span:contains('Co...
    程式設計 發佈於2024-11-06
  • 如何將 HTML 附加到容器元素而不出現 InnerHTML 陷阱?
    如何將 HTML 附加到容器元素而不出現 InnerHTML 陷阱?
    在沒有innerHTML的情況下將HTML附加到容器元素重新訪問當前的問題是如何將HTML附加到容器元素,同時避免限制以及使用innerHTML屬性的陷阱。正如OP正確指出的那樣,innerHTML由於其替換現有內容的行為,可能會破壞嵌入媒體等動態元素。 幸運的是,有一個替代方案可以克服這些問題:i...
    程式設計 發佈於2024-11-06

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

Copyright© 2022 湘ICP备2022001581号-3