”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > S - 单一职责原则(SRP)

S - 单一职责原则(SRP)

发布于2024-11-06
浏览:446

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]删除
最新教程 更多>
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-04-17
  • 在Python中如何创建动态变量?
    在Python中如何创建动态变量?
    在Python 中,动态创建变量的功能可以是一种强大的工具,尤其是在使用复杂的数据结构或算法时,Dynamic Variable Creation的动态变量创建。 Python提供了几种创造性的方法来实现这一目标。利用dictionaries 一种有效的方法是利用字典。字典允许您动态创建密钥并分...
    编程 发布于2025-04-17
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-17
  • 在Linux上如何精确测量C++函数执行时间?
    在Linux上如何精确测量C++函数执行时间?
    在C 中测量函数的执行时间,以评估C程序中特定函数的执行时间,可用多个时间测量技术。但是,对于Linux系统进行了准确的测量,建议使用BOOST.CHRONO的Process_USER_CPU_CLOCK函数。此函数确定CPU花费在执行指定功能的时间,不包括在其他过程或系统任务上花费的任何时间。这...
    编程 发布于2025-04-17
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-04-17
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-04-17
  • 可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    可以在纯CS中将多个粘性元素彼此堆叠在一起吗?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    编程 发布于2025-04-17
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-04-17
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-04-17
  • 如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
    编程 发布于2025-04-17
  • 在CUDA中如何处理2D和3D数组以获得最佳性能?
    在CUDA中如何处理2D和3D数组以获得最佳性能?
    cuda:揭开2D和3D数组的奥秘在使用CUDA中的2D和3D数组时会出现许多问题,并且矛盾的答案可能令人沮丧。要解决这些问题,让我们深入研究常见的解决方案及其含义: 2D数组分配:mallocpitch vs. flatten 对于真正的2D数组,推荐的方法正在变平。 By storing e...
    编程 发布于2025-04-17
  • 如何在无序集合中为元组实现通用哈希功能?
    如何在无序集合中为元组实现通用哈希功能?
    在未订购的集合中的元素要纠正此问题,一种方法是手动为特定元组类型定义哈希函数,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    编程 发布于2025-04-17
  • 如何使用Python理解有效地创建字典?
    如何使用Python理解有效地创建字典?
    在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
    编程 发布于2025-04-17
  • 如何使用组在MySQL中旋转数据?
    如何使用组在MySQL中旋转数据?
    在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
    编程 发布于2025-04-17
  • 解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    解决MySQL错误1153:数据包超出'max_allowed_packet'限制
    mysql错误1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的数据包,用于面对阴谋mysql错误1153,同时导入数据capase doft a Database dust?让我们深入研究罪魁祸首并探索解决方案以纠正此问题。理解错误此错误表明在导入过程中接...
    编程 发布于2025-04-17

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3