”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > I——接口隔离原则(ISP)

I——接口隔离原则(ISP)

发布于2024-11-08
浏览:476

I - Interface Segregation Principle (ISP)

What is Interface Segregation Principle(ISP) ?

The Interface Segregation Principle (ISP) is one of the SOLID principles in object-oriented programming, which focuses on designing interfaces so that no class is forced to implement methods it doesn't need.

In simple terms, ISP suggests that instead of creating large, all-encompassing interfaces, we should design smaller, more focused ones. This ensures that each class only implements the methods it actually requires.

For example:

If a large interface contains many functions, but a class doesn’t need all of those functions, it would still have to implement all of them—even if some are unnecessary. ISP suggests that we should split such large interfaces into smaller, more focused ones. This way, each class can implement only the functions it actually needs and avoid implementing unnecessary ones.

By following this approach, code complexity is reduced, making it easier to understand and maintain.

The main goals of ISP are:

  • Breaking down large and complex interfaces into smaller, more specific ones.

  • Ensuring that a class doesn’t need to implement unnecessary functionality.

  • Avoiding placing undue responsibility on a class, resulting in cleaner and more understandable code.

For example:

If an interface has 10 methods, but a specific class only needs 2 of them, ISP recommends splitting this large interface. This way, each class can implement only the methods it requires, without having to implement the others.

Example 1:

Let’s say we have a Worker interface that is used for all types of tasks:

Java code:

interface Worker {
    void work();
    void eat();
}

Now, there are two classes: HumanWorker and RobotWorker. HumanWorker can both eat and work, but RobotWorker cannot eat. Still, RobotWorker has to implement the eat() method, which violates ISP:

Java code:

class HumanWorker implements Worker {
    public void work() {
        System.out.println("Human is working");
    }
    public void eat() {
        System.out.println("Human is eating");
    }
}

class RobotWorker implements Worker {
    public void work() {
        System.out.println("Robot is working");
    }
    public void eat() {
        // Robot can't eat, but still needs to implement this method
    }
}

We can solve this problem using ISP by creating separate interfaces for working Workable and eating Eatable:

Java code:

interface Workable {
    void work();
}

interface Eatable {
    void eat();
}

class HumanWorker implements Workable, Eatable {
    public void work() {
        System.out.println("Human is working");
    }
    public void eat() {
        System.out.println("Human is eating");
    }
}

class RobotWorker implements Workable {
    public void work() {
        System.out.println("Robot is working");
    }
}

Now, RobotWorker no longer needs to implement the unnecessary eat() method, adhering to the Interface Segregation Principle (ISP).

Example 1:

Let's say there is a machine interface that can both run and recharge:

JavaScript code:

class Machine {
  run() {
    console.log("Machine is running");
  }

  recharge() {
    console.log("Machine is recharging");
  }
}

However, some machines can only run but cannot recharge. According to ISP, we should separate the responsibility of recharging into a different interface:

JavaScript code:

class RunnableMachine {
  run() {
    console.log("Machine is running");
  }
}

class RechargeableMachine {
  recharge() {
    console.log("Machine is recharging");
  }
}

Now, machines that don’t need to recharge only implement the run() method, while rechargeable machines implement the recharge() method. This separation follows the Interface Segregation Principle (ISP).

Example 2:

Let’s say there is a Printer class that can both print and scan:

JavaScript code:

class Printer {
  print() {
    console.log("Printing...");
  }

  scan() {
    console.log("Scanning...");
  }
}

However, not all printers have the ability to scan. In this case, we can separate the necessary methods into different interfaces:

JavaScript code:

class PrintOnly {
  print() {
    console.log("Printing...");
  }
}

class ScanAndPrint {
  print() {
    console.log("Printing...");
  }

  scan() {
    console.log("Scanning...");
  }
}

Now, printers that only need the print functionality will implement the PrintOnly class, while those that require both printing and scanning will implement the ScanAndPrint class. This design adheres to the Interface Segregation Principle (ISP), ensuring that each class only implements what it truly needs.

Example 3:

Let’s say we have a Vehicle class that can both drive and fly:

JavaScript code:

class Vehicle {
  drive() {
    console.log("Driving...");
  }

  fly() {
    console.log("Flying...");
  }
}

However, not all vehicles can fly. To solve this, we can create separate interfaces:

JavaScript code:

class DriveOnly {
  drive() {
    console.log("Driving...");
  }
}

class FlyAndDrive {
  drive() {
    console.log("Driving...");
  }

  fly() {
    console.log("Flying...");
  }
}

Now, vehicles that can only drive will implement the DriveOnly class, while vehicles that can both drive and fly will implement the FlyAndDrive class. This solution follows the Interface Segregation Principle (ISP), ensuring that classes only implement the functionality they need.

Importance and Real-Life Applications of ISP:

  1. Improves Code Maintainability: ISP ensures that classes are only required to implement the methods they need. This makes the code easier to maintain since classes aren’t cluttered with unnecessary methods.

  2. Use of Specific Interfaces: By using smaller, more focused interfaces instead of large, generalized ones, development becomes more efficient, as there’s no need to deal with unnecessary functionality.

  3. Real-Life Solution: Imagine you are working with different types of devices such as printers, scanners, and multifunction devices. Each device has its own specific set of tasks. Using ISP, you can create separate interfaces for each task (e.g., printing, scanning) so that each device only implements the functionalities it requires. This keeps the code clean and well-organized.

When to Use ISP:

  • When multiple classes have different requirements, instead of using a large, generalized interface, you should break it into smaller, more specific interfaces.

  • If you notice that a class is forced to implement methods that it doesn’t need or use, you can apply ISP to ensure the class only implements relevant functionality.

Problems Caused by Violating ISP:

  1. Unnecessary Method Implementation: When a class implements a large interface but does not use all the methods, it is forced to implement unnecessary methods. This leads to extraneous methods in the code that are not needed.

  2. Increased Code Complexity: Large interfaces can result in excessive responsibilities for classes, making the code unnecessarily complex. This complexity makes it difficult to maintain the code, and introducing new changes can become risky.

  3. Violation of Class Responsibilities: When ISP is violated, a class may have to implement methods that are not directly related to its core functionality. This also violates the Single Responsibility Principle (SRP), as the class becomes involved in tasks outside its primary role.

  4. Maintenance and Update Issues: When changes are made to a large interface, all classes that implement that interface must adjust to those changes. If smaller interfaces were used, only the relevant classes would need updates, making it easier to maintain consistency. Maintaining such consistency with large interfaces can become challenging.

  5. Decreased Code Reusability: Large interfaces force all classes to implement all methods, leading to decreased reusability. Each class may end up containing unnecessary code, which reduces the overall reusability of the code.

Example:

Suppose you have a large interface called Worker, which includes work() and eat() methods. Now, for a robot, there is no need for the eat() method, but the robot class is still required to implement it. This violates ISP and results in unnecessary methods that are irrelevant to the robot’s functionality.

Conclusion:

Thus, violating ISP leads to increased code complexity, makes maintenance difficult, and forces unnecessary method implementations.

Interface Segregation Principle(ISP) in React

The Interface Segregation Principle (ISP) simply states that an object or component should not be forced to implement methods that it does not use. Each component should be given methods or props that are relevant to its specific needs.

The core idea of ISP is that clients should not be provided with interfaces or APIs that they do not need to use. In simpler terms, it suggests breaking down large interfaces or classes into smaller, more focused ones, allowing clients to use only the parts that are necessary for them.

This approach promotes cleaner, more maintainable code and enhances the flexibility of the system by ensuring that each component interacts only with the functionalities it requires.

Simple Example:

Imagine a restaurant that has three types of customers: 1) those who come to eat rice, 2) those who come to eat pasta, and 3) those who come to eat salad. If we provide them all with the same menu that includes everything together, many items will be irrelevant to some customers. This would make the menu unnecessarily complicated for them.

According to the Interface Segregation Principle (ISP), the customer who comes for rice should only be given the rice menu, the pasta eater should only receive the pasta menu, and the salad eater should only get the salad menu. This way, the experience is simplified for everyone, allowing each customer to focus on what they actually want without any unnecessary options.

This analogy illustrates how ISP encourages tailoring interfaces to meet specific needs, making interactions more straightforward and efficient.

ISP in React Simplified:

In React, we often create large components that contain many props or methods. However, it's common for a component not to need all of those props. According to the Interface Segregation Principle (ISP), components should be broken down into smaller parts so that each component only receives the props and methods that are necessary for its functionality.

By following this principle, you can achieve:

  1. Cleaner Code: Each component remains focused on its specific task, making the codebase easier to understand and maintain.

  2. Improved Reusability: Smaller components can be reused in different contexts without carrying unnecessary props.

  3. Better Performance: Since components only receive what they need, rendering becomes more efficient.

For example, instead of a large UserProfile component that handles both user information and user settings, you could create two separate components: UserInfo and UserSettings. Each component would only receive the relevant props, following the ISP and resulting in a more modular and maintainable structure.

Example 1:

Imagine we have created a large Button component that can perform various actions such as onClick, onHover, onFocus, and more. However, in some cases, we might only need the onClick functionality, but the other functions also come with the component, which we don’t need.

According to the Interface Segregation Principle (ISP), we can break down this large Button component into smaller, more focused components. For example:

JSX code:

const ClickableButton = ({ onClick }) => (
  
);

const HoverableButton = ({ onHover }) => (
  
);

Example 2:

Imagine we have a large Form component that contains multiple fields (name, address, email, password). However, sometimes we only need the email and password fields, not the entire form component.

According to the Interface Segregation Principle (ISP), we can break down the form into smaller parts. For example:

JSX code:

const EmailField = ({ email, onChange }) => (
  
);

const PasswordField = ({ password, onChange }) => (
  
);

Now, when we only need the email and password, we can use just those specific components instead of the entire form component. This approach allows us to create a more focused and modular structure, adhering to ISP principles.

Example 3:

Imagine we have a large Dashboard component that includes various user information, graphs, and settings. However, there might be a page where we only need the user settings, yet we are using the entire Dashboard component.

According to the Interface Segregation Principle (ISP), we should break down the large Dashboard component into smaller, more focused parts. For example:

JSX code:

const UserInfo = ({ name, email }) => (
  

{name}

{email}

); const UserSettings = ({ settings }) => (

Settings

{/* Code to display the settings */}
);

Now, we can utilize these separate parts wherever necessary, allowing us to display only the relevant sections needed for that specific page. This approach ensures that our components are lightweight and tailored to their intended functionality.

Solution:

Following the Interface Segregation Principle (ISP), React components should be designed as separate, small interfaces or props tailored for specific tasks. This approach allows components to be easier to manage and used only as needed, promoting a more efficient and clean codebase.

By breaking down components into smaller, focused parts, we ensure that each component does one thing well, enhancing maintainability and making it easier to adapt or extend functionality in the future. This method also facilitates better reusability, as developers can select only the components that fit their requirements without carrying unnecessary baggage.

Disadvantages of Interface Segregation Principle(ISP)

While the Interface Segregation Principle (ISP) has several advantages, it also comes with some limitations. Below are some disadvantages of ISP:

  1. Need for More Interfaces: Following ISP often requires breaking large interfaces into smaller ones. This can lead to the creation of a large number of interfaces, making code management somewhat complex.

  2. Increased Coding and Maintenance: With many interfaces, each one requires a separate implementation. This increases the workload for developers and can take more time. Additionally, making changes later might necessitate updates in multiple places, complicating maintenance.

  3. Risk of Over-Engineering: ISP can sometimes introduce excessive complexity, especially when too many small interfaces are created. This approach may lead to over-engineering, resulting in unnecessary complexity for the project.

  4. Complex Dependency Management: Using ISP can make components or classes dependent on various interfaces. This can complicate dependency management, as multiple dependencies arise from several interfaces, making it difficult to keep track of them.

Summary

When applying ISP, issues such as the creation of excessive interfaces, increased coding, and management challenges can arise, which may escalate project complexity.

Conclusion

The Interface Segregation Principle (ISP) helps maintain modularity and flexibility in programming. By breaking down large interfaces or components into smaller parts, it eliminates unnecessary complexity. Using ISP allows us to implement only the necessary methods or props in a component, making the code simpler, more reusable, and maintainable. Although it can sometimes lead to an increase in interfaces and code, when applied correctly, it can greatly enhance the organization and effectiveness of software design. Therefore, proper implementation of ISP is essential for improved quality and long-term success in software development.

版本声明 本文转载于:https://dev.to/nozibul_islam_113b1d5334f/i-interface-segregation-principle-isp-33mi?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-07-18
  • Java为何无法创建泛型数组?
    Java为何无法创建泛型数组?
    通用阵列创建错误 arrayList [2]; JAVA报告了“通用数组创建”错误。为什么不允许这样做?答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<myO...
    编程 发布于2025-07-18
  • CSS可以根据任何属性值来定位HTML元素吗?
    CSS可以根据任何属性值来定位HTML元素吗?
    靶向html元素,在CSS 中使用任何属性值,在CSS中,可以基于特定属性(如下所示)基于特定属性的基于特定属性的emants目标元素: 字体家庭:康斯拉斯(Consolas); } 但是,出现一个常见的问题:元素可以根据任何属性值而定位吗?本文探讨了此主题。的目标元素有任何任何属性值,属...
    编程 发布于2025-07-18
  • Java中如何使用观察者模式实现自定义事件?
    Java中如何使用观察者模式实现自定义事件?
    在Java 中创建自定义事件的自定义事件在许多编程场景中都是无关紧要的,使组件能够基于特定的触发器相互通信。本文旨在解决以下内容:问题语句我们如何在Java中实现自定义事件以促进基于特定事件的对象之间的交互,定义了管理订阅者的类界面。以下代码片段演示了如何使用观察者模式创建自定义事件: args)...
    编程 发布于2025-07-18
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-07-18
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-07-18
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,将常数列添加到Spark DataFrame,该列具有适用于所有行的任意值的Spark DataFrame,可以通过多种方式实现。使用文字值(SPARK 1.3)在尝试提供直接值时,用于此问题时,旨在为此目的的column方法可能会导致错误。 df.withco...
    编程 发布于2025-07-18
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-07-18
  • 如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    如何使用Java.net.urlConnection和Multipart/form-data编码使用其他参数上传文件?
    使用http request 上传文件上传到http server,同时也提交其他参数,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    编程 发布于2025-07-18
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-07-18
  • 如何在鼠标单击时编程选择DIV中的所有文本?
    如何在鼠标单击时编程选择DIV中的所有文本?
    在鼠标上选择div文本单击带有文本内容,用户如何使用单个鼠标单击单击div中的整个文本?这允许用户轻松拖放所选的文本或直接复制它。 在单个鼠标上单击的div元素中选择文本,您可以使用以下Javascript函数: function selecttext(canduterid){ if(do...
    编程 发布于2025-07-18
  • 为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    class'ziparchive'在Linux Server上安装Archive_zip时找不到错误 commant in lin ins in cland ins in lin.11 on a lin.1 in a lin.11错误:致命错误:在... cass中找不到类z...
    编程 发布于2025-07-18
  • 为什么不使用CSS`content'属性显示图像?
    为什么不使用CSS`content'属性显示图像?
    在Firefox extemers属性为某些图像很大,&& && && &&华倍华倍[华氏华倍华氏度]很少见,却是某些浏览属性很少,尤其是特定于Firefox的某些浏览器未能在使用内容属性引用时未能显示图像的情况。这可以在提供的CSS类中看到:。googlepic { 内容:url(&#...
    编程 发布于2025-07-18
  • 如何检查对象是否具有Python中的特定属性?
    如何检查对象是否具有Python中的特定属性?
    方法来确定对象属性存在寻求一种方法来验证对象中特定属性的存在。考虑以下示例,其中尝试访问不确定属性会引起错误: >>> a = someClass() >>> A.property Trackback(最近的最新电话): 文件“ ”,第1行, AttributeError: SomeClass...
    编程 发布于2025-07-18
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    答案: 在大多数现代编译器中,while(1)和(1)和(;;)之间没有性能差异。编译器: perl: 1 输入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    编程 发布于2025-07-18

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

Copyright© 2022 湘ICP备2022001581号-3