Maison >Java >javaDidacticiel >I - Principe de ségrégation d'interface (ISP)

I - Principe de ségrégation d'interface (ISP)

Susan Sarandon
Susan Sarandonoriginal
2024-10-03 06:07:02986parcourir

I - Interface Segregation Principle (ISP)

Qu'est-ce que le principe de ségrégation d'interface (ISP) ?

Le principe de ségrégation des interfaces (ISP) est l'un des principes SOLID de la programmation orientée objet, qui se concentre sur la conception d'interfaces afin qu'aucune classe ne soit obligée d'implémenter des méthodes dont elle n'a pas besoin.

En termes simples, le FAI suggère qu'au lieu de créer de grandes interfaces globales, nous devrions en concevoir des plus petites et plus ciblées. Cela garantit que chaque classe implémente uniquement les méthodes dont elle a réellement besoin.

Par exemple:

Si une grande interface contient de nombreuses fonctions, mais qu'une classe n'a pas besoin de toutes ces fonctions, elle devra quand même toutes les implémenter, même si certaines sont inutiles. Le FAI suggère que nous devrions diviser ces grandes interfaces en interfaces plus petites et plus ciblées. De cette façon, chaque classe peut implémenter uniquement les fonctions dont elle a réellement besoin et éviter d'en implémenter des inutiles.

En suivant cette approche, la complexité du code est réduite, ce qui le rend plus facile à comprendre et à maintenir.

Les principaux objectifs du FAI sont :

  • Décomposer les interfaces volumineuses et complexes en interfaces plus petites et plus spécifiques.

  • S'assurer qu'une classe n'a pas besoin d'implémenter des fonctionnalités inutiles.

  • Éviter d'imposer une responsabilité excessive à une classe, ce qui permet d'obtenir un code plus propre et plus compréhensible.

Par exemple:

Si une interface dispose de 10 méthodes, mais qu'une classe spécifique n'en a besoin que de 2, le FAI recommande de diviser cette grande interface. De cette façon, chaque classe peut implémenter uniquement les méthodes dont elle a besoin, sans avoir à implémenter les autres.

Exemple 1 :

Disons que nous avons une interface Worker qui est utilisée pour tous les types de tâches :

Code Java :

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

Maintenant, il existe deux classes : HumanWorker et RobotWorker. HumanWorker peut à la fois manger et travailler, mais RobotWorker ne peut pas manger. Pourtant, RobotWorker doit implémenter la méthode eat(), ce qui viole le FAI :

Code Java :

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
    }
}

Nous pouvons résoudre ce problème en utilisant le FAI en créant des interfaces distinctes pour travailler Workable et manger Eatable :

Code Java :

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");
    }
}

Désormais, RobotWorker n'a plus besoin d'implémenter la méthode eat() inutile, adhérant au principe de ségrégation d'interface (ISP).

Exemple 1 :

Disons qu'il existe une interface machine qui peut à la fois fonctionner et se recharger :

Code JavaScript :

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

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

Cependant, certaines machines peuvent uniquement fonctionner mais ne peuvent pas se recharger. Selon le FAI, nous devrions séparer la responsabilité de la recharge dans une interface différente :

Code JavaScript :

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

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

Désormais, les machines qui n'ont pas besoin de se recharger implémentent uniquement la méthode run(), tandis que les machines rechargeables implémentent la méthode recharge(). Cette séparation suit le principe de ségrégation d'interface (ISP).

Exemple 2 :

Disons qu'il existe une classe d'imprimante qui peut à la fois imprimer et numériser :

Code JavaScript :

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

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

Cependant, toutes les imprimantes n’ont pas la capacité de numériser. Dans ce cas, on peut séparer les méthodes nécessaires en différentes interfaces :

Code JavaScript :

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

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

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

Désormais, les imprimantes qui n'ont besoin que de la fonctionnalité d'impression implémenteront la classe PrintOnly, tandis que celles qui nécessitent à la fois l'impression et la numérisation implémenteront la classe ScanAndPrint. Cette conception adhère au principe de ségrégation d'interface (ISP), garantissant que chaque classe n'implémente que ce dont elle a réellement besoin.

Exemple 3 :

Disons que nous avons une classe de véhicules qui peut à la fois conduire et voler :

Code JavaScript :

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

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

Cependant, tous les véhicules ne peuvent pas voler. Pour résoudre cela, nous pouvons créer des interfaces distinctes :

Code JavaScript :

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

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

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

Désormais, les véhicules qui peuvent uniquement conduire implémenteront la classe DriveOnly, tandis que les véhicules qui peuvent à la fois conduire et voler implémenteront la classe FlyAndDrive. Cette solution suit le principe de ségrégation d'interface (ISP), garantissant que les classes implémentent uniquement les fonctionnalités dont elles ont besoin.

Importance et applications réelles du FAI :

  1. Améliore la maintenabilité du code : ISP garantit que les classes ne sont nécessaires que pour implémenter les méthodes dont elles ont besoin. Cela rend le code plus facile à maintenir puisque les classes ne sont pas encombrées de méthodes inutiles.

  2. Utilisation d'interfaces spécifiques : En utilisant des interfaces plus petites et plus ciblées au lieu de grandes interfaces généralisées, le développement devient plus efficace, car il n'est pas nécessaire de gérer des fonctionnalités inutiles.

  3. Solution réelle : Imaginez que vous travaillez avec différents types d'appareils tels que des imprimantes, des scanners et des appareils multifonctions. Chaque appareil possède son propre ensemble de tâches spécifiques. À l'aide du FAI, vous pouvez créer des interfaces distinctes pour chaque tâche (par exemple, impression, numérisation) afin que chaque appareil implémente uniquement les fonctionnalités dont il a besoin. Cela permet de garder le code propre et bien organisé.

Quand utiliser le FAI :

  • Lorsque plusieurs classes ont des exigences différentes, au lieu d'utiliser une grande interface généralisée, vous devez la diviser en interfaces plus petites et plus spécifiques.

  • Si vous remarquez qu'une classe est obligée d'implémenter des méthodes dont elle n'a pas besoin ou qu'elle n'utilise pas, vous pouvez appliquer ISP pour vous assurer que la classe n'implémente que les fonctionnalités pertinentes.

Problèmes causés par une violation du FAI :

  1. Implémentation de méthodes inutiles : Lorsqu'une classe implémente une grande interface mais n'utilise pas toutes les méthodes, elle est obligée d'implémenter des méthodes inutiles. Cela conduit à des méthodes superflues dans le code qui ne sont pas nécessaires.

  2. Complexité accrue du code : Les grandes interfaces peuvent entraîner des responsabilités excessives pour les classes, rendant le code inutilement complexe. Cette complexité rend difficile la maintenance du code et l'introduction de nouveaux changements peut devenir risquée.

  3. Violation des responsabilités de classe : Lorsqu'un FAI est violé, une classe peut devoir implémenter des méthodes qui ne sont pas directement liées à sa fonctionnalité principale. Cela viole également le principe de responsabilité unique (SRP), car la classe est impliquée dans des tâches en dehors de son rôle principal.

  4. Problèmes de maintenance et de mise à jour : Lorsque des modifications sont apportées à une grande interface, toutes les classes qui implémentent cette interface doivent s'adapter à ces modifications. Si des interfaces plus petites étaient utilisées, seules les classes pertinentes auraient besoin de mises à jour, ce qui faciliterait le maintien de la cohérence. Maintenir une telle cohérence avec de grandes interfaces peut devenir un défi.

  5. Diminution de la réutilisabilité du code : Les grandes interfaces obligent toutes les classes à implémenter toutes les méthodes, ce qui entraîne une diminution de la réutilisabilité. Chaque classe peut finir par contenir du code inutile, ce qui réduit la réutilisabilité globale du code.

Exemple:

Supposons que vous disposiez d'une grande interface appelée Worker, qui inclut les méthodes work() et eat(). Désormais, pour un robot, la méthode eat() n’est pas nécessaire, mais la classe robot est toujours nécessaire pour l’implémenter. Cela viole le FAI et entraîne des méthodes inutiles qui ne sont pas pertinentes pour la fonctionnalité du robot.

Conclusion:

Ainsi, la violation du FAI entraîne une complexité accrue du code, rend la maintenance difficile et force l'implémentation de méthodes inutiles.

Principe de ségrégation d'interface (ISP) dans React

Le principe de ségrégation d'interface (ISP) stipule simplement qu'un objet ou un composant ne doit pas être forcé à implémenter des méthodes qu'il n'utilise pas. Chaque composant doit recevoir des méthodes ou des accessoires adaptés à ses besoins spécifiques.

L'idée centrale du FAI est que les clients ne doivent pas disposer d'interfaces ou d'API qu'ils n'ont pas besoin d'utiliser. En termes plus simples, cela suggère de diviser les grandes interfaces ou classes en plus petites et plus ciblées, permettant aux clients d'utiliser uniquement les parties qui leur sont nécessaires.

Cette approche favorise un code plus propre et plus maintenable et améliore la flexibilité du système en garantissant que chaque composant interagit uniquement avec les fonctionnalités dont il a besoin.

Exemple simple :

Imaginez un restaurant qui a trois types de clients : 1) ceux qui viennent manger du riz, 2) ceux qui viennent manger des pâtes, et 3) ceux qui viennent manger de la salade. Si nous fournissons tous avec le même menu qui comprend tout ensemble, de nombreux éléments ne seront pas pertinents pour certains clients. Cela rendrait le menu inutilement compliqué pour eux.

Selon le principe de ségrégation d'interface (ISP), le client qui vient chercher du riz ne doit recevoir que le menu de riz, le mangeur de pâtes ne doit recevoir que le menu de pâtes et le mangeur de salade ne doit recevoir que le menu de salades. De cette façon, l'expérience est simplifiée pour chacun, permettant à chaque client de se concentrer sur ce qu'il veut réellement sans aucune option inutile.

Cette analogie illustre comment les FAI encouragent l'adaptation des interfaces pour répondre à des besoins spécifiques, rendant les interactions plus simples et efficaces.

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 }) => (
  <button onClick={onClick}>Click Me</button>
);

const HoverableButton = ({ onHover }) => (
  <button onMouseOver={onHover}>Hover Over Me</button>
);

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 }) => (
  <input type="email" value={email} onChange={onChange} />
);

const PasswordField = ({ password, onChange }) => (
  <input type="password" value={password} onChange={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 }) => (
  <div>
    <p>{name}</p>
    <p>{email}</p>
  </div>
);

const UserSettings = ({ settings }) => (
  <div>
    <h3>Settings</h3>
    {/* Code to display the settings */}
  </div>
);

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. Gestion des dépendances complexes : L'utilisation d'ISP peut rendre des composants ou des classes dépendants de diverses interfaces. Cela peut compliquer la gestion des dépendances, car plusieurs dépendances proviennent de plusieurs interfaces, ce qui rend difficile leur suivi.

Résumé

Lors de l'application d'un FAI, des problèmes tels que la création d'interfaces excessives, une augmentation du codage et des défis de gestion peuvent survenir, ce qui peut aggraver la complexité du projet.

Conclusion

Le principe de ségrégation d'interface (ISP) permet de maintenir la modularité et la flexibilité de la programmation. En décomposant les grandes interfaces ou composants en parties plus petites, cela élimine la complexité inutile. L'utilisation d'ISP nous permet d'implémenter uniquement les méthodes ou accessoires nécessaires dans un composant, rendant le code plus simple, plus réutilisable et plus maintenable. Même si cela peut parfois conduire à une augmentation du nombre d’interfaces et de code, lorsqu’il est appliqué correctement, il peut grandement améliorer l’organisation et l’efficacité de la conception logicielle. Par conséquent, une mise en œuvre appropriée du FAI est essentielle pour améliorer la qualité et le succès à long terme du développement logiciel.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn