web-dev-qa-db-fra.com

Principe de fermeture ouverte (OCP) vs Principe d'inversion de dépendance (DIP)

J'essayais de comprendre la différence entre - principe fermé ouvert (OCP) et Inversion de dépendance princible (DIP).

Basé sur des recherches que j'ai faites sur Internet jusqu'à présent, je suis arrivé à la conclusion que "DIP est une option par laquelle nous pouvons atteindre OCP".

Je suis juste sur ça?

Pouvez-vous me donner un exemple qui ne suit pas la trempette mais suit OCP?

12
Jitendar

J'ai écrit une réponse précédemment sur principe ouverte (PRSP) VS Liskov (PSP) et ces principes se rapportent beaucoup aux autres, mais sont toujours conceptuellement différents avec des exemples d'enroulement mais pas l'autre. À cause de cette réponse, je ne toucherai plus brièvement à OCP et mangez plus profondément dans la trempette et ce qui rend cette coche.

Essayons de discuter de la manière dont le PCA concerne et diffère avec le principe d'inversion de dépendance (DIP) en expliquant d'abord les différents principes en premier.

Principe d'inversion de dépendance

Lecture principes de oods de l'oncle Bob Vous trouverez que DIP énonce ce qui suit:

Dépendent des abstractions, pas sur des concrétions.

Une abstraction in Java est simplement obtenue avec interface et abstract mots-clés, ce qui signifie que vous avez un "contrat" ​​pour une entité logicielle à suivre. Certaines langues de programmation ne disposent pas d'une installation pour définir explicitement les comportements pour le code à suivre afin que les abstractions doivent être suivies d'une manière plus manuelle plutôt que d'avoir le compilateur vous aider à appliquer le contrat. Par exemple, dans C++, vous avez des cours avec des méthodes virtuelles et Langues de programmation dynamiques telles que JavaScript, vous devez vous assurer que vous utilisez des objets de la même manière (bien que dans le cas de JavaScript, il a été étendu à TypeScript qui ajoute un système de type pour vous aider à sortir avec la rédaction de contrats vérifiés par le compilateur).

Le nom inclut le terme "inversion" car traditionnellement (tu sais que sur l'ancien âge sombre de la programmation) Vous avez écrit des structures logicielles ayant des modules de niveau supérieur en fonction des modules de faible niveau. Par exemple. Il était logique d'avoir un ButtonAtKitchen entrées de manipulation pour un KitchenLamp1 et KitchenLamp2. Malheureusement, cela a rendu un logiciel beaucoup plus spécifique que nécessaire pour être et le graphique d'objet ressemblerait à ceci:

ButtonAtKitchen handles KitchenLamp1 and KitchenLamp2

Ainsi, lorsque vous faites le logiciel plus général, en ajoutant des "contrats". Remarquez comment les flèches dans le graphique d'objet "inverse" la direction. Ces lampes de cuisine sont maintenant dépendantes d'un Button. En d'autres termes, les détails dépendent maintenant des abstractions au lieu de l'inverse.

KitchenButton now has a IButton abstraction that the kitchen lamps are dependent on

Ainsi, nous avons une définition plus générale de la DIP, également détaillée dans le Article original de DIP par oncle Bob .

A. Les modules de haut niveau ne doivent pas dépendre des modules de faible niveau. Les deux devraient dépendre de l'abstraction. B. Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions.

Principe ouvert

Suite des principes de l'oncle Bob vous constaterez que l'OCP indique ce qui suit:

Vous devriez être capable d'étendre un comportement de classes sans modifier.

Un exemple de réalisation de cela est d'utiliser le modèle de stratégie où une classe Context est fermé pour les modifications (c'est-à-dire que vous ne pouvez pas modifier son code interne du tout) mais est aussi Ouvrir pour l'extension à travers ses dépendances collaborant (c'est-à-dire les classes de stratégie).

Dans un sens plus général, tout module est conçu pour être extensible à travers ses points d'extension.

A module with extension points

OCP est similaire à la trempette, non?

Non, pas vraiment.

Bien qu'ils discutent tous deux des abstractions, ils sont conceptuels différents. Les deux principes examinent différents contextes, OCP sur un module particulier et plongent sur plusieurs modules. Vous pouvez réaliser les deux en même temps que la plupart des diagrammes de conception, mais vous pouvez toujours vous échapper du chemin.

Dans l'exemple de trempage mentionné ci-dessus, avec le bouton et les lampes de cuisine, Aucune des lampes de cuisine n'est extensible (ni aucune exigence en expliquant qu'elles doivent être). La conception est casser OCP mais suit DIP.

Un exemple inverse (et un artificiel) serait une lampe de cuisine être extensible (avec le point d'extension étant quelque chose comme un LampShade) mais le bouton est toujours dépendant des lampes. C'est Débarquez-vous, mais suit OCP.

Ne t'inquiète pas, ça arrive

C'est en fait quelque chose que vous verrez souvent dans le code de production, qu'une partie de cela peut briser un principe. Dans les systèmes logiciels plus grands (c'est-à-dire plus grand que les exemples ci-dessus), vous risquez de casser un principe mais de garder l'autre généralement parce que vous devez garder le code simple. C'est dans mon esprit d'accord pour les modules de petits et autonomes, car ils sont dans le contexte lié au principe de responsabilité unique (SRP).

Une fois que certains module deviennent compliqués bien que vous deviez probablement le regarder avec tous les principes en tête et à la refonte ou refacteur cela à un motif bien connu.

16
Spoike