Principe de responsabilité unique
La définition du principe de responsabilité unique est que pour une classe, il ne devrait y avoir qu’une seule raison pour son changement. En d’autres termes, une classe ne devrait être responsable que d’une seule chose. Si une classe est responsable de deux choses différentes, la méthode M1 et la méthode M2, lorsque la méthode M1 change, nous devons modifier la méthode M1 de cette classe, mais pour le moment, la méthode M2 peut ne pas fonctionner. Ce n’est pas ce à quoi nous nous attendions, mais c’est tout à fait possible grâce à cette conception. Donc à ce stade, nous devons séparer la méthode M1 et la méthode M2 en deux classes. Laissez chaque classe se concentrer uniquement sur ses propres méthodes.
Les avantages du principe de responsabilité unique sont les suivants :
Cela peut réduire la complexité de la classe. Chaque classe n'est responsable que d'une seule responsabilité. Cela rend la logique beaucoup plus simple et améliore la lisibilité de la classe et la maintenabilité du système, car il n'y aura pas d'autres méthodes étranges qui interfèrent avec notre. compréhension de la signification de cette classe. Lorsque des changements se produisent, l'impact des changements peut être minimisé car les modifications ne seront apportées que dans cette classe.
Principe d'ouverture et de fermeture
Le principe ouvert-fermé, comme le principe de responsabilité unique, est un principe très fondamental et généralement de bon sens. La définition du principe ouvert-fermé est que les objets (classes, modules, fonctions, etc.) dans un logiciel doivent être ouverts pour extension, mais fermés pour modification.
Lorsque les exigences changent, nous devons modifier le code. À ce stade, nous devrions essayer d'étendre le code d'origine au lieu de modifier le code d'origine, car cela pourrait causer davantage de problèmes.
Ce principe est le même que le principe de responsabilité unique. C'est un principe selon lequel tout le monde le pense mais ne précise pas comment le faire.
Nous pouvons garantir le principe d'ouverture et de fermeture d'une manière. Nous utilisons l'abstraction pour construire le cadre et la mise en œuvre pour étendre les détails. De cette façon, lorsqu'une modification se produit, nous utilisons directement l'abstraction pour dériver une classe concrète pour implémenter la modification.
Principe de substitution de Richter
Le principe de substitution de Liskov est un concept très utile. Sa définition
Si pour chaque objet o1 de type T1, il existe un objet o2 de type T2, de sorte que le comportement de tous les programmes P définis avec T1 ne change pas lorsque tous les objets o1 sont remplacés par o2, alors le type T2 est un sous-type de type T1.
C'est un peu compliqué à dire ça, mais il existe en fait une définition simple
Toutes les références à une classe de base doivent pouvoir utiliser de manière transparente les objets de ses sous-classes.
En termes simples, le principe de substitution de Liskov est le suivant : les sous-classes peuvent étendre les fonctions de la classe parent, mais elles ne peuvent pas modifier les fonctions d'origine de la classe parent. Il contient les significations suivantes :
Les sous-classes peuvent implémenter les méthodes abstraites de la classe parent, mais elles ne peuvent pas remplacer les méthodes non abstraites de la classe parent.
Les sous-classes peuvent ajouter leurs propres méthodes uniques.
Lorsqu'une méthode de sous-classe remplace une méthode de classe parent, les paramètres formels de la méthode sont plus souples que les paramètres d'entrée de la méthode de classe parent.
Lorsqu'une méthode d'une sous-classe implémente une méthode abstraite d'une classe parent, la valeur de retour de la méthode est plus stricte que celle de la classe parent.
La raison pour laquelle le principe de substitution de Liskov l'exige est que l'héritage présente de nombreux inconvénients. Bien qu'il s'agisse d'une méthode de réutilisation du code, l'héritage viole l'encapsulation dans une certaine mesure. Les attributs et méthodes de la classe parent sont transparents pour la sous-classe, et la sous-classe peut modifier les membres de la classe parent à volonté. Cela entraîne également que si les exigences changent et que la sous-classe remplace certaines méthodes de la classe parent, les autres sous-classes ne pourront pas fonctionner correctement. La règle de substitution de Richter a donc été proposée.
S'assurer que le programme suit le principe de substitution de Liskov nécessite que notre programme établisse des abstractions, établisse des spécifications par abstraction, puis utilise l'implémentation pour étendre les détails. Oui, le principe de substitution de Liskov et le principe d'ouverture et de fermeture sont souvent interdépendants.
Principe d'inversion de dépendance
Le principe d'inversion de dépendance fait référence à une manière particulière de découplage, de sorte que les modules de haut niveau ne doivent pas dépendre des détails d'implémentation des modules de bas niveau et que les modules dépendants sont inversés. C'est aussi une définition difficile à comprendre. On peut simplement la dire comme
. Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau, les deux doivent dépendre de leurs abstractions. Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions
. En Java, l'abstraction fait référence à des interfaces ou à des classes abstraites, dont aucune ne peut être instanciée. Les détails sont les classes d'implémentation, qui sont des classes qui implémentent des interfaces ou héritent de classes abstraites. Il peut être instancié. Le module de haut niveau fait référence à l'extrémité appelante et le module de bas niveau est la classe d'implémentation spécifique. En Java, le principe d'inversion de dépendance signifie que les dépendances entre modules se produisent par abstraction. Il n'y a pas de dépendance directe entre les classes d'implémentation et leurs dépendances sont réalisées via des interfaces. C'est ce qu'on appelle communément la programmation orientée interface.
Nous avons un exemple ci-dessous pour illustrer ce problème. Cet exemple est celui d’un ouvrier utilisant un marteau pour réparer quelque chose. Notre code est le suivant :
marteau de classe publique {
fonction de chaîne publique(){
return "Utilisez un marteau pour réparer les choses";
}
}
travailleur de classe publique {
correctif du vide public(Marteau){
System.out.println("worker" + marteau.function());
}
public static void main(String[] args) {
nouveau travailleur(). correctif (nouveau marteau ());
}
}
C'est un exemple très simple, mais si l'on veut ajouter une nouvelle fonction, les ouvriers utilisent des tournevis pour réparer des choses. Dans cette classe, nous trouvons que c'est difficile à faire. Parce que notre classe Worker dépend d'une classe d'implémentation spécifique Hammer. Nous utilisons donc l'idée de programmation orientée interface et la modifions par le code suivant :
outils d'interface publique {
fonction de chaîne publique ();
}
Ensuite, notre Worker s'appuie sur d'autres classes de détails via cette interface. Le code est le suivant :
Travailleur de classe publique {
correctif du vide public (outil Outils) {
System.out.println("worker" + tool.function());
}
public static void main(String[] args) {
newWorker(). correctif (nouveau marteau ());
newWorker(). réparer (nouveau tournevis ());
}
}
Notre classe Hammer et notre classe Tournevis implémentent cette interface
classe publique Hammer implémente des outils{
fonction de chaîne publique(){
return "Utilisez un marteau pour réparer les choses";
}
}
classe publique Tournevis met en œuvre des outils{
@Override
fonction de chaîne publique() {
return "Utilisez un tournevis pour réparer quelque chose";
}
}
De cette manière, grâce à une programmation orientée interface, notre code présente une grande évolutivité, réduit le couplage entre les codes et améliore la stabilité du système.
Principe d'isolation de l'interface
La définition du principe d'isolation de l'interface est
Le client ne doit pas s'appuyer sur des interfaces dont il n'a pas besoin
En d’autres termes, les dépendances entre classes doivent être établies sur la plus petite interface. Cela semble plus difficile à comprendre. Illustrons avec un exemple. Nous savons que si une classe concrète implémente une interface en Java, elle doit implémenter toutes les méthodes de l'interface. Si nous avons une classe A et une classe B qui dépendent de l'interface I, la classe B est l'implémentation de la dépendance de la classe A, et cette interface I a 5 méthodes. Mais les classes A et B dépendent uniquement des méthodes 1, 2 et 3, puis les classes C et D dépendent de l'interface I. La classe D est une implémentation de dépendance à la classe C, mais elles dépendent des méthodes 1, 4 et 5. Ensuite, lors de l'implémentation de l'interface, la classe B doit implémenter la méthode 4 et la méthode 5 dont elle n'a pas besoin, et la classe D doit implémenter la méthode 2 et la méthode 3 dont elle n'a pas besoin. Il s’agit simplement d’une conception catastrophe.
Nous devons donc diviser l'interface, c'est-à-dire diviser l'interface en la plus petite interface qui réponde aux dépendances. La classe B et la classe D n'ont pas besoin d'implémenter des méthodes d'interface qui n'ont rien à voir avec elles. Par exemple, dans cet exemple, nous pouvons diviser l'interface en trois. La première est une interface qui contient uniquement la méthode 1, la deuxième interface contient les méthodes 2 et 3 et la troisième interface contient les méthodes 4 et 5. De cette façon, notre conception satisfait au principe d’isolation des interfaces.
Les idées de conception ci-dessus peuvent être transformées en SOLID avec les premières lettres de l'anglais. Les programmes qui répondent à ces cinq principes sont également considérés comme répondant aux critères SOLID.
Principe de Dimit
Le principe Dimit est également appelé principe de connaissance minimum, et sa définition est
Un objet doit conserver une connaissance minimale des autres objets.
Parce que plus la relation entre les classes est étroite, plus le degré de couplage est élevé. Lorsqu'une classe change, plus l'impact sur l'autre classe est grand. C'est donc également le principe général de la programmation logicielle que nous préconisons : faible couplage, couplage élevé. Cohésion. Il existe une définition plus simple de la loi de Déméter
Communiquez uniquement avec des amis directs. Tout d’abord, expliquons ce qu’est un ami direct : chaque objet aura une relation de couplage avec d’autres objets. Tant qu’il existe une relation de couplage entre deux objets, on dit que les deux objets sont amis. Il existe de nombreuses méthodes de couplage, telles que la dépendance, l'association, la combinaison, l'agrégation, etc. Parmi eux, nous appelons les classes qui apparaissent dans les variables membres, les paramètres de méthode et les valeurs de retour de méthode des amis directs, tandis que les classes qui apparaissent dans les variables locales ne sont pas des amis directs. En d’autres termes, il est préférable que des classes inconnues n’apparaissent pas à l’intérieur de la classe en tant que variables locales.
Ici, nous pouvons utiliser un exemple réel pour expliquer. Par exemple, si nous avons besoin d'un CD, nous pouvons aller au vidéoclub et demander au patron s'il a le CD dont nous avons besoin. Le patron dit qu'il n'a pas le CD dont nous avons besoin pour le moment et que vous pouvez simplement venir le chercher. quand il est disponible. Ici, nous n'avons pas besoin de nous soucier de l'endroit ou de la manière dont le patron a obtenu le CD. Nous communiquons uniquement avec le patron (ami direct). Quant aux conditions dans lesquelles le patron a obtenu le CD de son ami, nous ne nous en soucions pas. Nous ne sommes pas d'accord avec lui. Les amis (étrangers) du patron communiquent. C'est une application de Dimit. Pour parler franchement, il s’agit d’une méthode intermédiaire. Nous utilisons le patron comme intermédiaire pour contacter la personne qui fournit effectivement le CD.
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!