Table des matières
1. OCP
Nom complet : « Principe ouvert-fermé » Principe ouvert-fermé
Description : Ouvert pour extension, fermé pour modification.
Avantages : Le système conçu selon les principes OCP réduit le couplage entre les différentes parties du programme, et son adaptabilité, sa flexibilité et sa stabilité sont relativement bonnes. Lorsque de nouvelles fonctions doivent être ajoutées à un système logiciel existant, il n'est pas nécessaire de modifier la couche d'abstraction qui constitue la base du système. Seuls de nouveaux modules doivent être ajoutés à la base d'origine pour réaliser les fonctions qui doivent être ajoutées. . Les nouveaux modules ajoutés n'ont pas ou très peu d'impact sur les modules d'origine, il n'est donc pas nécessaire de retester les modules d'origine.
Comment implémenter le principe "ouvert-fermé"
Dans la conception orientée objet, ce qui n'est pas autorisé à changer est la couche d'abstraction du système, mais ce qui peut être étendu est la couche d'implémentation du système . En d’autres termes, définissez une couche de conception d’abstraction une fois pour toutes qui permet d’implémenter autant de comportements que possible au niveau de la couche d’implémentation.
La clé pour résoudre les problèmes réside dans l’abstraction, qui est la première essence de la conception orientée objet.
Abstraire quelque chose, c'est essentiellement résumer son essence. L'abstraction nous permet de saisir les choses les plus importantes et de penser à un niveau supérieur. Cela réduit la complexité de la réflexion et nous n’avons pas besoin de penser à tant de choses en même temps. En d’autres termes, nous encapsulons l’essence des choses et ne pouvons voir aucun détail.
Dans la programmation orientée objet, à travers les classes abstraites et les interfaces, les caractéristiques des classes concrètes sont stipulées comme une couche d'abstraction, qui est relativement stable et n'a pas besoin d'être modifiée, satisfaisant ainsi l'exigence d'être « fermée à la modification » tandis que les classes concrètes dérivées de classes abstraites peuvent être modifiées. Le comportement du système afin qu'il satisfasse à "l'ouverture à l'extension".
Lors de l'extension de l'entité, il n'est pas nécessaire de modifier le code source ou le code binaire du logiciel. La clé est l’abstraction.

2. LSP
Nom complet : "Principe de substitution de Liskov" Principe de substitution de Liskov

Remarque : le sous-type doit être capable de remplacer leurs types de base. Si une entité logicielle utilise une classe de base, lorsque la classe de base est remplacée par une sous-classe qui hérite de la classe de base, le comportement du programme ne changera pas. Les entités logicielles ne connaissent pas la différence entre les objets de classe de base et les objets de sous-classe.
Avantages : Il est facile de réaliser l'échange de sous-classes sous la même classe parent sans que le client s'en rende compte.

3. DIP
Nom complet : "Principe d'inversion de dépendance" Principe d'inversion de dépendance

Explication : Dépend de l'abstraction, pas du concret. Les clients s'appuient sur un couplage abstrait.
L'abstraction ne devrait pas dépendre des détails ; les détails devraient dépendre de l'abstraction ;
La programmation devrait être destinée aux interfaces, pas à l'implémentation ;
Avantages : En utilisant les dépendances créées par la programmation procédurale traditionnelle, la stratégie dépend des détails, ce qui est mauvais car la stratégie est affectée par les changements dans les détails. Le principe d'inversion de dépendance rend les détails et les stratégies dépendants de l'abstraction, et la stabilité de l'abstraction détermine la stabilité du système.
Comment réaliser l’inversion des dépendances ?
Le couplage de manière abstraite est la clé du principe d'inversion de dépendance. Les relations de couplage abstraites impliquent toujours des classes concrètes héritant de classes abstraites, et il est nécessaire de garantir que toute référence à la classe de base puisse être modifiée en sa sous-classe. Par conséquent, le principe de substitution de Liskov est la base du principe d'inversion de dépendance.
Bien que le couplage au niveau abstrait soit flexible, il apporte également une complexité supplémentaire. Si la possibilité de changement de classe spécifique est très faible, alors les avantages du couplage abstrait seront très limités. mieux vaut utiliser un couplage en béton.
Hiérarchie : toutes les architectures orientées objet bien structurées ont des définitions de couches claires, et chaque couche fournit un ensemble de services cohérents vers l'extérieur via une interface bien définie et contrôlée.
Dépend de l'abstraction : il est recommandé de ne pas s'appuyer sur des classes concrètes, c'est-à-dire que toutes les dépendances du programme doivent se terminer par des classes ou des interfaces abstraites. Essayez de faire ce qui suit :
1. Aucune variable ne doit contenir un pointeur ou une référence à une classe spécifique.
2. Aucune classe ne doit être dérivée d'une classe concrète.
3. Aucune méthode ne doit remplacer la méthode implémentée dans aucune de ses classes de base.

4. FAI
Nom complet : "Principe de ségrégation des interfaces" Principe d'isolation des interfaces

Explication : Il est toujours préférable d'utiliser plusieurs interfaces de fonctions dédiées plutôt que d'utiliser une seule interface totale. . Du point de vue d'une classe client : la dépendance d'une classe par rapport à une autre classe doit être basée sur l'interface minimale. Une interface trop pléthorique est une pollution de l’interface et ne doit pas obliger les clients à s’appuyer sur des méthodes qu’ils n’utilisent pas.
Avantages : Lorsqu'une fonction d'un système logiciel est étendue, la pression de modification ne sera pas transmise aux autres objets.
Comment mettre en œuvre le principe d'isolation des interfaces
Les utilisateurs ne devraient pas être obligés de s’appuyer sur des méthodes qu’ils n’utilisent pas.
1. Utilisez la délégation pour séparer les interfaces.
2. Utilisez l'héritage multiple pour séparer les interfaces.

5. CARP ou CRP
Nom complet : « Composite
e/Principe de réutilisation des agrégats » Principe de réutilisation de la synthèse/agrégation ou « Principe de réutilisation composite"
Principe de réutilisation composite
Remarque : Si certaines fonctions du nouvel objet ont été implémentées dans d'autres objets déjà créés, essayez d'utiliser d'autres objets Fournissez des fonctionnalités pour qu'il devient partie intégrante du nouvel objet plutôt que de le recréer vous-même. Les nouveaux objets permettent de réutiliser les fonctionnalités existantes en déléguant à ces objets.
En bref, essayez d'utiliser la composition/agrégation et essayez de ne pas utiliser l'héritage.
Avantages :
1) Le seul moyen pour un nouvel objet d'accéder aux objets composants est via l'interface de l'objet composant.
2) Ce type de réutilisation est une réutilisation en boîte noire, car les détails internes des objets composants sont invisibles pour le nouvel objet.
3) Ce type de réutilisation soutient les emballages.
4) Ce type de réutilisation nécessite moins de dépendances.
5) Chaque nouvelle classe peut se concentrer sur une tâche.
6) Ce type de réutilisation peut être effectué dynamiquement pendant l'exécution, et les nouveaux objets peuvent référencer dynamiquement des objets du même type que les objets composants.
7) En tant que méthode de réutilisation, elle peut être appliquée à presque tous les environnements.
Inconvénients :
Autrement dit, il y aura plus d'objets dans le système qui devront être gérés.

6. LOD ou LKP
Nom complet : « Loi de Déméter » Principe de Déméter ou « Principe de moindre connaissance » Principe de moindre connaissance

Explication : Les objets doivent être liés le moins de manières possible pour éviter des relations inextricables.
Comment mettre en œuvre la loi de Déméter
L'objectif principal de la loi de Déméter est de contrôler la surcharge d'informations Lorsque vous l'appliquez à la conception du système, vous devez faire attention aux points suivants :
1) En termes de classe. division, les classes doivent être créées avec un couplage faible. Plus le couplage entre classes est faible, plus il est facile de les réutiliser.
2) En termes de conception de la structure des classes, chaque classe doit minimiser les droits d'accès des membres. Une classe ne doit pas rendre ses propriétés publiques, mais doit fournir des méthodes pour obtenir et attribuer des valeurs afin de permettre au monde extérieur d'accéder indirectement à ses propriétés.
3) Dans la conception de classe, dans la mesure du possible, une classe doit être conçue pour être une classe immuable.
4) En termes de références à d'autres objets, les références d'une classe à d'autres objets doivent être minimisées.


Il existe également un principe de responsabilité unique :

SRP--Principe de responsabilité unique) : en ce qui concerne une classe, elle ne doit se concentrer que sur Faites une chose et n'ayez qu'une seule raison pour que cela change
. Les soi-disant responsabilités peuvent être comprises comme des fonctions, c'est-à-dire que la fonction conçue ne doit avoir qu'une seule fonction, et non deux ou plus. Cela peut également être compris comme la raison du changement de référence. Lorsque vous constatez qu'il y a deux changements qui nous obligeront à modifier cette classe, vous devriez alors envisager de retirer cette classe. La responsabilité étant un axe de changement, lorsque les exigences changent, le changement reflétera l'évolution des responsabilités de la classe. Points à noter lors de l'utilisation du SRP : 1. Une classe raisonnable ne devrait avoir qu'une seule raison pour son changement, c'est-à-dire une seule responsabilité
2. Il n'est pas judicieux d'appliquer le SRP ou d'autres principes sans signes de changement
; 3. Lorsque les exigences changent réellement, des principes tels que SRP doivent être appliqués pour refactoriser le code ;
4. L'utilisation du développement piloté par les tests nous obligera à séparer le code déraisonnable avant que la conception ne sente
5. Si vous ne pouvez pas forcer la séparation des responsabilités, l'odeur de rigidité et de fragilité deviendra très forte, alors vous devez utiliser le mode Façade ou Proxy pour refactoriser le code ; avantages SRP : éliminer le couplage et réduire la rigidité du code causée par les changements d'exigences.


Vous n'êtes pas obligé d'adhérer strictement à ces principes, et il n'y a aucune sanction religieuse en cas de violation. Mais vous devez considérer ces principes comme une sonnette d’alarme. Si l’un d’entre eux est violé, la sonnette d’alarme retentit.
-----Arthur J.Riel
(1) Toutes les données doivent être cachées à l'intérieur de la classe où elles se trouvent.
(2) Les utilisateurs d'une classe doivent s'appuyer sur l'interface partagée de la classe, mais une classe ne peut pas s'appuyer sur ses utilisateurs. p15
(3) Minimiser les messages dans le protocole de classe.
(4) Implémentez l'interface publique la plus élémentaire que toutes les classes comprennent [par exemple, les opérations de copie (copie profonde et copie superficielle), le jugement d'égalité, le contenu de sortie correct, l'analyse à partir de la description ASCII, etc.]. p16
(5) Ne mettez pas les détails d'implémentation (tels que les fonctions privées qui placent du code partagé) dans l'interface publique de la classe.
Si deux méthodes d'une classe ont un code commun, alors vous pouvez créer une fonction privée qui empêche ces codes communs.
(6) Ne perturbez pas l'interface publique d'une classe avec des éléments que les utilisateurs ne peuvent pas utiliser ou qui ne les intéressent pas. p17
(7) Il ne devrait y avoir aucun couplage entre les classes, ou uniquement des relations de couplage dérivées. Autrement dit, soit une classe n'a rien à voir avec une autre classe, soit elle utilise uniquement des opérations dans l'interface publique d'une autre classe. p18
(8) Les classes ne doivent représenter qu'une seule abstraction clé.
Toutes les classes du package doivent être fermées conjointement pour les modifications du même type de propriétés. Si un changement affecte un package, il affectera toutes les classes du package, mais n'aura aucun impact sur les autres packages
(9) Centraliser les données et les comportements associés.
Les concepteurs doivent prêter attention aux objets qui obtiennent des données d'autres objets via des opérations telles que get. Ce type de comportement implique que ce principe empirique est violé.
(10) Mettez les informations non pertinentes dans une autre classe (c'est-à-dire le comportement de ne pas communiquer entre eux). p19
Évoluez vers des dépendances stables
(11) Assurez-vous que le concept abstrait que vous modélisez est une classe, pas seulement le rôle joué par un objet. p23
(12) Répartir les fonctions du système aussi uniformément que possible dans le sens horizontal, c'est-à-dire : selon la conception, les classes de niveau supérieur doivent partager le travail de manière uniforme.
(13) Ne créez pas de classes/objets omnipotents dans votre système. Soyez particulièrement prudent avec les classes dont les noms incluent Driver, Manager, System et Susystem.
Planifier une interface plutôt que mettre en œuvre une interface.
(14) Soyez prudent avec les classes qui définissent un grand nombre de méthodes d'accès dans l'interface publique. Le grand nombre de méthodes d’accès signifie que les données et comportements pertinents ne sont pas stockés de manière centralisée.
(15) Attention aux cours qui contiennent trop de comportements qui ne communiquent pas entre eux.
Une autre manifestation de ce problème est la création de nombreuses fonctions get et set dans l'interface publique de la classe de votre application.
(16) Dans une application composée d'un modèle orienté objet qui interagit avec l'interface utilisateur, le modèle ne doit pas dépendre de l'interface, mais l'interface doit dépendre du modèle.
(17) Modéliser autant que possible en fonction du monde réel (nous violons souvent ce principe afin de respecter le principe de distribution des fonctions du système, d'éviter le principe de classe polyvalent et de placer de manière centralisée les données et les comportements associés) .
(18) Supprimez les classes inutiles de votre conception.
De manière générale, nous déclasserons cette classe en propriété.
(19) Supprimer les classes en dehors du système.
La caractéristique des classes extérieures au système est que, en termes abstraits, elles envoient uniquement des messages au domaine système mais n'acceptent pas les messages des autres classes du domaine système.
(20)Ne transformez pas les opérations en cours. Interrogez toute classe dont le nom est un verbe ou dérivé d'un verbe, en particulier une classe avec une seule action significative. Déterminez si ce comportement significatif doit être déplacé vers une classe qui existe déjà ou qui n’a pas encore été découverte.
(21) Nous introduisons souvent des classes proxy lors de la création de modèles d'analyse d'applications. Lors de la phase de conception, nous constatons souvent que de nombreux agents sont inutiles et doivent être supprimés.
(22) Essayez de réduire le nombre de collaborateurs d'une classe.
Le nombre d'autres classes utilisées par une classe doit être aussi réduit que possible.
(23) Minimisez le nombre de messages transmis entre les classes et les collaborateurs.
(24) Minimiser la quantité de collaboration entre les classes et les collaborateurs, c'est-à-dire : réduire le nombre de messages différents transmis entre les classes et les collaborateurs.
(25) Minimiser la diffusion de la classe, c'est-à-dire : réduire le produit du nombre de messages définis par la classe et du nombre de messages envoyés
(26) Si la classe contient des objets d'une autre classe , alors la classe conteneur doit être L'objet contenu envoie le message. Autrement dit : une relation d’inclusion implique toujours une relation d’usage.
(27) La plupart des méthodes définies dans une classe doivent utiliser la plupart des données membres la plupart du temps.


(28) Le nombre d'objets contenus dans une classe ne doit pas dépasser la capacité de la mémoire à court terme du développeur. Ce nombre est souvent 6.
Lorsqu'une classe contient plus de 6 données membres, vous pouvez diviser les données membres logiquement liées en un groupe, puis utiliser une nouvelle classe conteneur pour contenir ce groupe de membres.
(29) Laissez les fonctions du système être distribuées verticalement dans un système d'héritage étroit et profond.
(30) Lors de l'implémentation de contraintes sémantiques, il est préférable de les implémenter en fonction des définitions de classe. Cela conduit souvent à un débordement de classe, auquel cas les contraintes doivent être implémentées dans le comportement de la classe, généralement mais pas nécessairement dans le constructeur.
(31) Lors de l'implémentation de contraintes sémantiques dans le constructeur d'une classe, placez le test de contrainte dans le niveau d'inclusion le plus profond autorisé par le champ constructeur.
(32) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent fréquemment, alors il est préférable de les placer dans un objet tiers centralisé.
(33) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent rarement, alors. il est mieux réparti entre les différentes classes impliquées dans les contraintes.
(34)Une classe doit savoir ce qu'elle contient, mais elle ne peut pas savoir qui le contient.
(35) Les objets qui partagent une portée littérale (c'est-à-dire contenus dans la même classe) ne doivent pas avoir de relation d'utilisation les uns avec les autres.
(36) L'héritage ne doit être utilisé que pour modéliser des hiérarchies de spécialisation.
(37) Les classes dérivées doivent connaître la classe de base, et les classes de base ne doivent connaître aucune information sur leurs classes dérivées.
(38) Toutes les données de la classe de base doivent être privées, n'utilisez pas de données protégées.

Les concepteurs de classe ne devraient jamais placer dans des interfaces publiques des éléments dont les utilisateurs de la classe n'ont pas besoin.
(39) En théorie, la hiérarchie d'héritage devrait être plus profonde, plus c'est profond, mieux c'est.
(40)En pratique, la profondeur de la hiérarchie successorale ne doit pas dépasser la capacité de mémoire à court terme d'une personne moyenne. Une valeur de profondeur largement acceptée est 6
(41) Toutes les classes abstraites doivent être des classes de base
(42) Toutes les classes de base doivent être des classes abstraites
(43) Placez les points communs dans les données, les comportements et/ou les interfaces aussi haut que possible dans la hiérarchie d'héritage.
(44) Si deux classes ou plus partagent des données communes (mais aucun comportement commun), alors les données communes doivent être placées dans une classe, et chaque classe qui partage ces données contient cette classe.
(45) Si deux classes ou plus ont des données et un comportement communs (c'est-à-dire des méthodes), alors chacune de ces classes doit hériter d'une classe de base commune qui représente ces données et méthodes. (46) Si deux classes ou plus partagent une interface commune (faisant référence à des messages et non à des méthodes), elles ne devraient alors hériter d'une classe de base commune que si elles doivent être utilisées de manière polymorphe. (47) L'analyse au cas par cas de l'affichage des types d'objets est généralement erronée. Dans la plupart de ces cas, les concepteurs doivent utiliser le polymorphisme.
(48) L'analyse au cas par cas de l'affichage des valeurs d'attribut est souvent erronée. Les classes doivent être découplées dans une hiérarchie d'héritage, chaque valeur d'attribut étant transformée en classe dérivée.


(49) Ne modélisez pas la sémantique dynamique d'une classe à travers des relations d'héritage. Tenter de modéliser une sémantique dynamique avec des relations sémantiques statiques entraîne un changement de type au moment de l'exécution.
(50)Ne transformez pas les objets de classe en classes dérivées. Soyez prudent avec toute classe dérivée qui n'a qu'une seule instance.
(51) Si vous pensez que vous devez créer une nouvelle classe au moment de l'exécution, prenez du recul et réalisez que vous créez des objets. Maintenant, généralisons ces objets dans une classe.
(52) Il devrait être illégal d'utiliser une méthode vide (c'est-à-dire une méthode qui ne fait rien) dans une classe dérivée pour remplacer une méthode dans la classe de base.
(53) Ne confondez pas l’inclusion facultative avec la nécessité d’un héritage. La modélisation de l'inclusion facultative comme héritage conduit à une prolifération de classes.
(54) Lors de la création de hiérarchies d'héritage, essayez de créer des frameworks réutilisables plutôt que des composants réutilisables.
(55) Si vous utilisez l'héritage multiple dans votre conception, supposez que vous avez commis une erreur. Si vous n’avez pas commis d’erreur, vous devez essayer de le prouver.
(56) Tant que l'héritage est utilisé dans la conception orientée objet, posez-vous deux questions : (1) La classe dérivée est-elle un type spécial de la chose dont elle hérite ? (2) La classe de base fait-elle partie de la classe dérivée ?
(57) Si vous trouvez plusieurs relations d'héritage dans une conception orientée objet, assurez-vous qu'aucune classe de base n'est en réalité une classe dérivée d'une autre classe de base.
(58) Dans la conception orientée objet, si vous devez choisir entre l'inclusion et l'association, veuillez choisir l'inclusion.
(59) N'utilisez pas de données globales ou de fonctions globales pour la comptabilité des objets de classe. Des variables de classe ou des méthodes de classe doivent être utilisées.
(60) Les concepteurs orientés objet ne devraient pas laisser les principes de conception physique miner leurs conceptions logiques. Cependant, nous utilisons souvent des critères de conception physique pour prendre des décisions concernant la conception logique.
(61) Ne contournez pas l'interface publique pour modifier l'état de l'objet. " >Il est très difficile de rendre un logiciel très flexible et facile à maintenir. Les logiciels flexibles ont une structure complexe et sont difficiles à maintenir. Il y a des gains et des pertes, et la clé réside dans la manière de gérer les deux afin que les pertes l’emportent sur les pertes. La conception et le développement du logiciel doivent suivre les six principes suivants :
1. OCP
Nom complet : « Principe ouvert-fermé » Principe ouvert-fermé

Description : Ouvert pour extension, fermé pour modification.
Avantages : Le système conçu selon les principes OCP réduit le couplage entre les différentes parties du programme, et son adaptabilité, sa flexibilité et sa stabilité sont relativement bonnes. Lorsque de nouvelles fonctions doivent être ajoutées à un système logiciel existant, il n'est pas nécessaire de modifier la couche d'abstraction qui constitue la base du système. Seuls de nouveaux modules doivent être ajoutés à la base d'origine pour réaliser les fonctions qui doivent être ajoutées. . Les nouveaux modules ajoutés n'ont pas ou très peu d'impact sur les modules d'origine, il n'est donc pas nécessaire de retester les modules d'origine.
Comment implémenter le principe "ouvert-fermé"
Dans la conception orientée objet, ce qui n'est pas autorisé à changer est la couche d'abstraction du système, mais ce qui peut être étendu est la couche d'implémentation du système . En d’autres termes, définissez une couche de conception d’abstraction une fois pour toutes qui permet d’implémenter autant de comportements que possible au niveau de la couche d’implémentation.
La clé pour résoudre les problèmes réside dans l’abstraction, qui est la première essence de la conception orientée objet.
Abstraire quelque chose, c'est essentiellement résumer son essence. L'abstraction nous permet de saisir les choses les plus importantes et de penser à un niveau supérieur. Cela réduit la complexité de la réflexion et nous n’avons pas besoin de penser à tant de choses en même temps. En d’autres termes, nous encapsulons l’essence des choses et ne pouvons voir aucun détail.
Dans la programmation orientée objet, à travers les classes abstraites et les interfaces, les caractéristiques des classes concrètes sont stipulées comme une couche d'abstraction, qui est relativement stable et n'a pas besoin d'être modifiée, satisfaisant ainsi l'exigence d'être « fermée à la modification » tandis que les classes concrètes dérivées de classes abstraites peuvent être modifiées. Le comportement du système afin qu'il satisfasse à "l'ouverture à l'extension".
Lors de l'extension de l'entité, il n'est pas nécessaire de modifier le code source ou le code binaire du logiciel. La clé est l’abstraction.

2. LSP
Nom complet : "Principe de substitution de Liskov" Principe de substitution de Liskov

Remarque : le sous-type doit être capable de remplacer leurs types de base. Si une entité logicielle utilise une classe de base, lorsque la classe de base est remplacée par une sous-classe qui hérite de la classe de base, le comportement du programme ne changera pas. Les entités logicielles ne connaissent pas la différence entre les objets de classe de base et les objets de sous-classe.
Avantages : Il est facile de réaliser l'échange de sous-classes sous la même classe parent sans que le client s'en rende compte.

3. DIP
Nom complet : "Principe d'inversion de dépendance" Principe d'inversion de dépendance

Explication : Dépend de l'abstraction, pas du concret. Les clients s'appuient sur un couplage abstrait.
L'abstraction ne devrait pas dépendre des détails ; les détails devraient dépendre de l'abstraction ;
La programmation devrait être destinée aux interfaces, pas à l'implémentation ;
Avantages : En utilisant les dépendances créées par la programmation procédurale traditionnelle, la stratégie dépend des détails, ce qui est mauvais car la stratégie est affectée par les changements dans les détails. Le principe d'inversion de dépendance rend les détails et les stratégies dépendants de l'abstraction, et la stabilité de l'abstraction détermine la stabilité du système.
Comment réaliser l’inversion des dépendances ?
Le couplage de manière abstraite est la clé du principe d'inversion de dépendance. Les relations de couplage abstraites impliquent toujours des classes concrètes héritant de classes abstraites, et il est nécessaire de garantir que toute référence à la classe de base puisse être modifiée en sa sous-classe. Par conséquent, le principe de substitution de Liskov est la base du principe d'inversion de dépendance.
Bien que le couplage au niveau abstrait soit flexible, il apporte également une complexité supplémentaire. Si la possibilité de changement de classe spécifique est très faible, alors les avantages du couplage abstrait seront très limités. mieux vaut utiliser un couplage en béton.
Hiérarchie : toutes les architectures orientées objet bien structurées ont des définitions de couches claires, et chaque couche fournit un ensemble de services cohérents vers l'extérieur via une interface bien définie et contrôlée.
Dépend de l'abstraction : il est recommandé de ne pas s'appuyer sur des classes concrètes, c'est-à-dire que toutes les dépendances du programme doivent se terminer par des classes ou des interfaces abstraites. Essayez de faire ce qui suit :
1. Aucune variable ne doit contenir un pointeur ou une référence à une classe spécifique.
2. Aucune classe ne doit être dérivée d'une classe concrète.
3. Aucune méthode ne doit remplacer la méthode implémentée dans aucune de ses classes de base.

4. FAI
Nom complet : "Principe de ségrégation des interfaces" Principe d'isolation des interfaces

Explication : Il est toujours préférable d'utiliser plusieurs interfaces de fonctions dédiées plutôt que d'utiliser une seule interface totale. . Du point de vue d'une classe client : la dépendance d'une classe par rapport à une autre classe doit être basée sur l'interface minimale. Une interface trop pléthorique est une pollution de l’interface et ne doit pas obliger les clients à s’appuyer sur des méthodes qu’ils n’utilisent pas.
Avantages : Lorsqu'une fonction d'un système logiciel est étendue, la pression de modification ne sera pas transmise aux autres objets.
Comment mettre en œuvre le principe d'isolation des interfaces
Les utilisateurs ne devraient pas être obligés de s’appuyer sur des méthodes qu’ils n’utilisent pas.
1. Utilisez la délégation pour séparer les interfaces.
2. Utilisez l'héritage multiple pour séparer les interfaces.

5. CARP ou CRP
Nom complet : « Composite
e/Principe de réutilisation des agrégats » Principe de réutilisation de la synthèse/agrégation ou « Principe de réutilisation composite"
Principe de réutilisation composite
Remarque : Si certaines fonctions du nouvel objet ont été implémentées dans d'autres objets déjà créés, essayez d'utiliser d'autres objets Fournissez des fonctionnalités pour qu'il devient partie intégrante du nouvel objet plutôt que de le recréer vous-même. Les nouveaux objets permettent de réutiliser les fonctionnalités existantes en déléguant à ces objets.
En bref, essayez d'utiliser la composition/agrégation et essayez de ne pas utiliser l'héritage.
Avantages :
1) Le seul moyen pour un nouvel objet d'accéder aux objets composants est via l'interface de l'objet composant.
2) Ce type de réutilisation est une réutilisation en boîte noire, car les détails internes des objets composants sont invisibles pour le nouvel objet.
3) Ce type de réutilisation soutient les emballages.
4) Ce type de réutilisation nécessite moins de dépendances.
5) Chaque nouvelle classe peut se concentrer sur une tâche.
6) Ce type de réutilisation peut être effectué dynamiquement pendant l'exécution, et les nouveaux objets peuvent référencer dynamiquement des objets du même type que les objets composants.
7) En tant que méthode de réutilisation, elle peut être appliquée à presque tous les environnements.
Inconvénients :
Autrement dit, il y aura plus d'objets dans le système qui devront être gérés.

6. LOD ou LKP
Nom complet : « Loi de Déméter » Principe de Déméter ou « Principe de moindre connaissance » Principe de moindre connaissance

Explication : Les objets doivent être liés le moins de manières possible pour éviter des relations inextricables.
Comment mettre en œuvre la loi de Déméter
L'objectif principal de la loi de Déméter est de contrôler la surcharge d'informations Lorsque vous l'appliquez à la conception du système, vous devez faire attention aux points suivants :
1) En termes de classe. division, les classes doivent être créées avec un couplage faible. Plus le couplage entre classes est faible, plus il est facile de les réutiliser.
2) En termes de conception de la structure des classes, chaque classe doit minimiser les droits d'accès des membres. Une classe ne doit pas rendre ses propriétés publiques, mais doit fournir des méthodes pour obtenir et attribuer des valeurs afin de permettre au monde extérieur d'accéder indirectement à ses propriétés.
3) Dans la conception de classe, dans la mesure du possible, une classe doit être conçue pour être une classe immuable.
4) En termes de références à d'autres objets, les références d'une classe à d'autres objets doivent être minimisées.


Il existe également un principe de responsabilité unique :

SRP--Principe de responsabilité unique) : en ce qui concerne une classe, elle ne doit se concentrer que sur Faites une chose et n'ayez qu'une seule raison pour que cela change
. Les soi-disant responsabilités peuvent être comprises comme des fonctions, c'est-à-dire que la fonction conçue ne doit avoir qu'une seule fonction, et non deux ou plus. Cela peut également être compris comme la raison du changement de référence. Lorsque vous constatez qu'il y a deux changements qui nous obligeront à modifier cette classe, vous devriez alors envisager de retirer cette classe. La responsabilité étant un axe de changement, lorsque les exigences changent, le changement reflétera l'évolution des responsabilités de la classe. Points à noter lors de l'utilisation du SRP : 1. Une classe raisonnable ne devrait avoir qu'une seule raison pour son changement, c'est-à-dire une seule responsabilité
2. Il n'est pas judicieux d'appliquer le SRP ou d'autres principes sans signes de changement
; 3. Lorsque les exigences changent réellement, des principes tels que SRP doivent être appliqués pour refactoriser le code ;
4. L'utilisation du développement piloté par les tests nous obligera à séparer le code déraisonnable avant que la conception ne sente
5. Si vous ne pouvez pas forcer la séparation des responsabilités, l'odeur de rigidité et de fragilité deviendra très forte, alors vous devez utiliser le mode Façade ou Proxy pour refactoriser le code ; avantages SRP : éliminer le couplage et réduire la rigidité du code causée par les changements d'exigences.


Vous n'êtes pas obligé d'adhérer strictement à ces principes, et il n'y a aucune sanction religieuse en cas de violation. Mais vous devez considérer ces principes comme une sonnette d’alarme. Si l’un d’entre eux est violé, la sonnette d’alarme retentit.
-----Arthur J.Riel
(1) Toutes les données doivent être cachées à l'intérieur de la classe où elles se trouvent.
(2) Les utilisateurs d'une classe doivent s'appuyer sur l'interface partagée de la classe, mais une classe ne peut pas s'appuyer sur ses utilisateurs. p15
(3) Minimiser les messages dans le protocole de classe.
(4) Implémentez l'interface publique la plus élémentaire que toutes les classes comprennent [par exemple, les opérations de copie (copie profonde et copie superficielle), le jugement d'égalité, le contenu de sortie correct, l'analyse à partir de la description ASCII, etc.]. p16
(5) Ne mettez pas les détails d'implémentation (tels que les fonctions privées qui placent du code partagé) dans l'interface publique de la classe.
Si deux méthodes d'une classe ont un code commun, alors vous pouvez créer une fonction privée qui empêche ces codes communs.
(6) Ne perturbez pas l'interface publique d'une classe avec des éléments que les utilisateurs ne peuvent pas utiliser ou qui ne les intéressent pas. p17
(7) Il ne devrait y avoir aucun couplage entre les classes, ou uniquement des relations de couplage dérivées. Autrement dit, soit une classe n'a rien à voir avec une autre classe, soit elle utilise uniquement des opérations dans l'interface publique d'une autre classe. p18
(8) Les classes ne doivent représenter qu'une seule abstraction clé.
Toutes les classes du package doivent être fermées conjointement pour les modifications du même type de propriétés. Si un changement affecte un package, il affectera toutes les classes du package, mais n'aura aucun impact sur les autres packages
(9) Centraliser les données et les comportements associés.
Les concepteurs doivent prêter attention aux objets qui obtiennent des données d'autres objets via des opérations telles que get. Ce type de comportement implique que ce principe empirique est violé.
(10) Mettez les informations non pertinentes dans une autre classe (c'est-à-dire le comportement de ne pas communiquer entre eux). p19
Évoluez vers des dépendances stables
(11) Assurez-vous que le concept abstrait que vous modélisez est une classe, pas seulement le rôle joué par un objet. p23
(12) Répartir les fonctions du système aussi uniformément que possible dans le sens horizontal, c'est-à-dire : selon la conception, les classes de niveau supérieur doivent partager le travail de manière uniforme.
(13) Ne créez pas de classes/objets omnipotents dans votre système. Soyez particulièrement prudent avec les classes dont les noms incluent Driver, Manager, System et Susystem.
Planifier une interface plutôt que mettre en œuvre une interface.
(14) Soyez prudent avec les classes qui définissent un grand nombre de méthodes d'accès dans l'interface publique. Le grand nombre de méthodes d’accès signifie que les données et comportements pertinents ne sont pas stockés de manière centralisée.
(15) Attention aux cours qui contiennent trop de comportements qui ne communiquent pas entre eux.
Une autre manifestation de ce problème est la création de nombreuses fonctions get et set dans l'interface publique de la classe de votre application.
(16) Dans une application composée d'un modèle orienté objet qui interagit avec l'interface utilisateur, le modèle ne doit pas dépendre de l'interface, mais l'interface doit dépendre du modèle.
(17) Modéliser autant que possible en fonction du monde réel (nous violons souvent ce principe afin de respecter le principe de distribution des fonctions du système, d'éviter le principe de classe polyvalent et de placer de manière centralisée les données et les comportements associés) .
(18) Supprimez les classes inutiles de votre conception.
De manière générale, nous déclasserons cette classe en propriété.
(19) Supprimer les classes en dehors du système.
La caractéristique des classes extérieures au système est que, en termes abstraits, elles envoient uniquement des messages au domaine système mais n'acceptent pas les messages des autres classes du domaine système.
(20)Ne transformez pas les opérations en cours. Interrogez toute classe dont le nom est un verbe ou dérivé d'un verbe, en particulier une classe avec une seule action significative. Déterminez si ce comportement significatif doit être déplacé vers une classe qui existe déjà ou qui n’a pas encore été découverte.
(21) Nous introduisons souvent des classes proxy lors de la création de modèles d'analyse d'applications. Lors de la phase de conception, nous constatons souvent que de nombreux agents sont inutiles et doivent être supprimés.
(22) Essayez de réduire le nombre de collaborateurs d'une classe.
Le nombre d'autres classes utilisées par une classe doit être aussi réduit que possible.
(23) Minimisez le nombre de messages transmis entre les classes et les collaborateurs.
(24) Minimiser la quantité de collaboration entre les classes et les collaborateurs, c'est-à-dire : réduire le nombre de messages différents transmis entre les classes et les collaborateurs.
(25) Minimiser la diffusion de la classe, c'est-à-dire : réduire le produit du nombre de messages définis par la classe et du nombre de messages envoyés
(26) Si la classe contient des objets d'une autre classe , alors la classe conteneur doit être L'objet contenu envoie le message. Autrement dit : une relation d’inclusion implique toujours une relation d’usage.
(27) La plupart des méthodes définies dans une classe doivent utiliser la plupart des données membres la plupart du temps.


(28) Le nombre d'objets contenus dans une classe ne doit pas dépasser la capacité de la mémoire à court terme du développeur. Ce nombre est souvent 6.
Lorsqu'une classe contient plus de 6 données membres, vous pouvez diviser les données membres logiquement liées en un groupe, puis utiliser une nouvelle classe conteneur pour contenir ce groupe de membres.
(29) Laissez les fonctions du système être distribuées verticalement dans un système d'héritage étroit et profond.
(30) Lors de l'implémentation de contraintes sémantiques, il est préférable de les implémenter en fonction des définitions de classe. Cela conduit souvent à un débordement de classe, auquel cas les contraintes doivent être implémentées dans le comportement de la classe, généralement mais pas nécessairement dans le constructeur.
(31) Lors de l'implémentation de contraintes sémantiques dans le constructeur d'une classe, placez le test de contrainte dans le niveau d'inclusion le plus profond autorisé par le champ constructeur.
(32) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent fréquemment, alors il est préférable de les placer dans un objet tiers centralisé.
(33) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent rarement, alors. il est mieux réparti entre les différentes classes impliquées dans les contraintes.
(34)Une classe doit savoir ce qu'elle contient, mais elle ne peut pas savoir qui le contient.
(35) Les objets qui partagent une portée littérale (c'est-à-dire contenus dans la même classe) ne doivent pas avoir de relation d'utilisation les uns avec les autres.
(36) L'héritage ne doit être utilisé que pour modéliser des hiérarchies de spécialisation.
(37) Les classes dérivées doivent connaître la classe de base, et les classes de base ne doivent connaître aucune information sur leurs classes dérivées.
(38) Toutes les données de la classe de base doivent être privées, n'utilisez pas de données protégées.

Les concepteurs de classe ne devraient jamais placer dans des interfaces publiques des éléments dont les utilisateurs de la classe n'ont pas besoin.
(39) En théorie, la hiérarchie d'héritage devrait être plus profonde, plus c'est profond, mieux c'est.
(40)En pratique, la profondeur de la hiérarchie successorale ne doit pas dépasser la capacité de mémoire à court terme d'une personne moyenne. Une valeur de profondeur largement acceptée est 6
(41) Toutes les classes abstraites doivent être des classes de base
(42) Toutes les classes de base doivent être des classes abstraites
(43) Placez les points communs dans les données, les comportements et/ou les interfaces aussi haut que possible dans la hiérarchie d'héritage.
(44) Si deux classes ou plus partagent des données communes (mais aucun comportement commun), alors les données communes doivent être placées dans une classe, et chaque classe qui partage ces données contient cette classe.
(45) Si deux classes ou plus ont des données et un comportement communs (c'est-à-dire des méthodes), alors chacune de ces classes doit hériter d'une classe de base commune qui représente ces données et méthodes. (46) Si deux classes ou plus partagent une interface commune (faisant référence à des messages et non à des méthodes), elles ne devraient alors hériter d'une classe de base commune que si elles doivent être utilisées de manière polymorphe. (47) L'analyse au cas par cas de l'affichage des types d'objets est généralement erronée. Dans la plupart de ces cas, les concepteurs doivent utiliser le polymorphisme.
(48) L'analyse au cas par cas de l'affichage des valeurs d'attribut est souvent erronée. Les classes doivent être découplées dans une hiérarchie d'héritage, chaque valeur d'attribut étant transformée en classe dérivée.


(49) Ne modélisez pas la sémantique dynamique d'une classe à travers des relations d'héritage. Tenter de modéliser une sémantique dynamique avec des relations sémantiques statiques entraîne un changement de type au moment de l'exécution.
(50)Ne transformez pas les objets de classe en classes dérivées. Soyez prudent avec toute classe dérivée qui n'a qu'une seule instance.
(51) Si vous pensez que vous devez créer une nouvelle classe au moment de l'exécution, prenez du recul et réalisez que vous créez des objets. Maintenant, généralisons ces objets dans une classe.
(52) Il devrait être illégal d'utiliser une méthode vide (c'est-à-dire une méthode qui ne fait rien) dans une classe dérivée pour remplacer une méthode dans la classe de base.
(53) Ne confondez pas l’inclusion facultative avec la nécessité d’un héritage. La modélisation de l'inclusion facultative comme héritage conduit à une prolifération de classes.
(54) Lors de la création de hiérarchies d'héritage, essayez de créer des frameworks réutilisables plutôt que des composants réutilisables.
(55) Si vous utilisez l'héritage multiple dans votre conception, supposez que vous avez commis une erreur. Si vous n’avez pas commis d’erreur, vous devez essayer de le prouver.
(56) Tant que l'héritage est utilisé dans la conception orientée objet, posez-vous deux questions : (1) La classe dérivée est-elle un type spécial de la chose dont elle hérite ? (2) La classe de base fait-elle partie de la classe dérivée ?
(57) Si vous trouvez plusieurs relations d'héritage dans une conception orientée objet, assurez-vous qu'aucune classe de base n'est en réalité une classe dérivée d'une autre classe de base.
(58) Dans la conception orientée objet, si vous devez choisir entre l'inclusion et l'association, veuillez choisir l'inclusion.
(59) N'utilisez pas de données globales ou de fonctions globales pour la comptabilité des objets de classe. Des variables de classe ou des méthodes de classe doivent être utilisées.
(60) Les concepteurs orientés objet ne devraient pas laisser les principes de conception physique miner leurs conceptions logiques. Cependant, nous utilisons souvent des critères de conception physique pour prendre des décisions concernant la conception logique.
(61) Ne contournez pas l'interface publique pour modifier l'état de l'objet.
Maison développement back-end tutoriel php Que sont les principes orientés objet

Que sont les principes orientés objet

Oct 12, 2017 am 09:13 AM
原则 对象 面向

Il est très difficile de rendre un logiciel très flexible et facile à maintenir. Les logiciels flexibles ont une structure complexe et sont difficiles à maintenir. Il y a des gains et des pertes, et la clé réside dans la manière de gérer les deux afin que les pertes l’emportent sur les pertes. La conception et le développement du logiciel doivent suivre les six principes suivants :
1. OCP
Nom complet : « Principe ouvert-fermé » Principe ouvert-fermé

Description : Ouvert pour extension, fermé pour modification.
Avantages : Le système conçu selon les principes OCP réduit le couplage entre les différentes parties du programme, et son adaptabilité, sa flexibilité et sa stabilité sont relativement bonnes. Lorsque de nouvelles fonctions doivent être ajoutées à un système logiciel existant, il n'est pas nécessaire de modifier la couche d'abstraction qui constitue la base du système. Seuls de nouveaux modules doivent être ajoutés à la base d'origine pour réaliser les fonctions qui doivent être ajoutées. . Les nouveaux modules ajoutés n'ont pas ou très peu d'impact sur les modules d'origine, il n'est donc pas nécessaire de retester les modules d'origine.
Comment implémenter le principe "ouvert-fermé"
Dans la conception orientée objet, ce qui n'est pas autorisé à changer est la couche d'abstraction du système, mais ce qui peut être étendu est la couche d'implémentation du système . En d’autres termes, définissez une couche de conception d’abstraction une fois pour toutes qui permet d’implémenter autant de comportements que possible au niveau de la couche d’implémentation.
La clé pour résoudre les problèmes réside dans l’abstraction, qui est la première essence de la conception orientée objet.
Abstraire quelque chose, c'est essentiellement résumer son essence. L'abstraction nous permet de saisir les choses les plus importantes et de penser à un niveau supérieur. Cela réduit la complexité de la réflexion et nous n’avons pas besoin de penser à tant de choses en même temps. En d’autres termes, nous encapsulons l’essence des choses et ne pouvons voir aucun détail.
Dans la programmation orientée objet, à travers les classes abstraites et les interfaces, les caractéristiques des classes concrètes sont stipulées comme une couche d'abstraction, qui est relativement stable et n'a pas besoin d'être modifiée, satisfaisant ainsi l'exigence d'être « fermée à la modification » tandis que les classes concrètes dérivées de classes abstraites peuvent être modifiées. Le comportement du système afin qu'il satisfasse à "l'ouverture à l'extension".
Lors de l'extension de l'entité, il n'est pas nécessaire de modifier le code source ou le code binaire du logiciel. La clé est l’abstraction.

2. LSP
Nom complet : "Principe de substitution de Liskov" Principe de substitution de Liskov

Remarque : le sous-type doit être capable de remplacer leurs types de base. Si une entité logicielle utilise une classe de base, lorsque la classe de base est remplacée par une sous-classe qui hérite de la classe de base, le comportement du programme ne changera pas. Les entités logicielles ne connaissent pas la différence entre les objets de classe de base et les objets de sous-classe.
Avantages : Il est facile de réaliser l'échange de sous-classes sous la même classe parent sans que le client s'en rende compte.

3. DIP
Nom complet : "Principe d'inversion de dépendance" Principe d'inversion de dépendance

Explication : Dépend de l'abstraction, pas du concret. Les clients s'appuient sur un couplage abstrait.
L'abstraction ne devrait pas dépendre des détails ; les détails devraient dépendre de l'abstraction ;
La programmation devrait être destinée aux interfaces, pas à l'implémentation ;
Avantages : En utilisant les dépendances créées par la programmation procédurale traditionnelle, la stratégie dépend des détails, ce qui est mauvais car la stratégie est affectée par les changements dans les détails. Le principe d'inversion de dépendance rend les détails et les stratégies dépendants de l'abstraction, et la stabilité de l'abstraction détermine la stabilité du système.
Comment réaliser l’inversion des dépendances ?
Le couplage de manière abstraite est la clé du principe d'inversion de dépendance. Les relations de couplage abstraites impliquent toujours des classes concrètes héritant de classes abstraites, et il est nécessaire de garantir que toute référence à la classe de base puisse être modifiée en sa sous-classe. Par conséquent, le principe de substitution de Liskov est la base du principe d'inversion de dépendance.
Bien que le couplage au niveau abstrait soit flexible, il apporte également une complexité supplémentaire. Si la possibilité de changement de classe spécifique est très faible, alors les avantages du couplage abstrait seront très limités. mieux vaut utiliser un couplage en béton.
Hiérarchie : toutes les architectures orientées objet bien structurées ont des définitions de couches claires, et chaque couche fournit un ensemble de services cohérents vers l'extérieur via une interface bien définie et contrôlée.
Dépend de l'abstraction : il est recommandé de ne pas s'appuyer sur des classes concrètes, c'est-à-dire que toutes les dépendances du programme doivent se terminer par des classes ou des interfaces abstraites. Essayez de faire ce qui suit :
1. Aucune variable ne doit contenir un pointeur ou une référence à une classe spécifique.
2. Aucune classe ne doit être dérivée d'une classe concrète.
3. Aucune méthode ne doit remplacer la méthode implémentée dans aucune de ses classes de base.

4. FAI
Nom complet : "Principe de ségrégation des interfaces" Principe d'isolation des interfaces

Explication : Il est toujours préférable d'utiliser plusieurs interfaces de fonctions dédiées plutôt que d'utiliser une seule interface totale. . Du point de vue d'une classe client : la dépendance d'une classe par rapport à une autre classe doit être basée sur l'interface minimale. Une interface trop pléthorique est une pollution de l’interface et ne doit pas obliger les clients à s’appuyer sur des méthodes qu’ils n’utilisent pas.
Avantages : Lorsqu'une fonction d'un système logiciel est étendue, la pression de modification ne sera pas transmise aux autres objets.
Comment mettre en œuvre le principe d'isolation des interfaces
Les utilisateurs ne devraient pas être obligés de s’appuyer sur des méthodes qu’ils n’utilisent pas.
1. Utilisez la délégation pour séparer les interfaces.
2. Utilisez l'héritage multiple pour séparer les interfaces.

5. CARP ou CRP
Nom complet : « Composite
e/Principe de réutilisation des agrégats » Principe de réutilisation de la synthèse/agrégation ou « Principe de réutilisation composite"
Principe de réutilisation composite
Remarque : Si certaines fonctions du nouvel objet ont été implémentées dans d'autres objets déjà créés, essayez d'utiliser d'autres objets Fournissez des fonctionnalités pour qu'il devient partie intégrante du nouvel objet plutôt que de le recréer vous-même. Les nouveaux objets permettent de réutiliser les fonctionnalités existantes en déléguant à ces objets.
En bref, essayez d'utiliser la composition/agrégation et essayez de ne pas utiliser l'héritage.
Avantages :
1) Le seul moyen pour un nouvel objet d'accéder aux objets composants est via l'interface de l'objet composant.
2) Ce type de réutilisation est une réutilisation en boîte noire, car les détails internes des objets composants sont invisibles pour le nouvel objet.
3) Ce type de réutilisation soutient les emballages.
4) Ce type de réutilisation nécessite moins de dépendances.
5) Chaque nouvelle classe peut se concentrer sur une tâche.
6) Ce type de réutilisation peut être effectué dynamiquement pendant l'exécution, et les nouveaux objets peuvent référencer dynamiquement des objets du même type que les objets composants.
7) En tant que méthode de réutilisation, elle peut être appliquée à presque tous les environnements.
Inconvénients :
Autrement dit, il y aura plus d'objets dans le système qui devront être gérés.

6. LOD ou LKP
Nom complet : « Loi de Déméter » Principe de Déméter ou « Principe de moindre connaissance » Principe de moindre connaissance

Explication : Les objets doivent être liés le moins de manières possible pour éviter des relations inextricables.
Comment mettre en œuvre la loi de Déméter
L'objectif principal de la loi de Déméter est de contrôler la surcharge d'informations Lorsque vous l'appliquez à la conception du système, vous devez faire attention aux points suivants :
1) En termes de classe. division, les classes doivent être créées avec un couplage faible. Plus le couplage entre classes est faible, plus il est facile de les réutiliser.
2) En termes de conception de la structure des classes, chaque classe doit minimiser les droits d'accès des membres. Une classe ne doit pas rendre ses propriétés publiques, mais doit fournir des méthodes pour obtenir et attribuer des valeurs afin de permettre au monde extérieur d'accéder indirectement à ses propriétés.
3) Dans la conception de classe, dans la mesure du possible, une classe doit être conçue pour être une classe immuable.
4) En termes de références à d'autres objets, les références d'une classe à d'autres objets doivent être minimisées.


Il existe également un principe de responsabilité unique :

SRP--Principe de responsabilité unique) : en ce qui concerne une classe, elle ne doit se concentrer que sur Faites une chose et n'ayez qu'une seule raison pour que cela change
. Les soi-disant responsabilités peuvent être comprises comme des fonctions, c'est-à-dire que la fonction conçue ne doit avoir qu'une seule fonction, et non deux ou plus. Cela peut également être compris comme la raison du changement de référence. Lorsque vous constatez qu'il y a deux changements qui nous obligeront à modifier cette classe, vous devriez alors envisager de retirer cette classe. La responsabilité étant un axe de changement, lorsque les exigences changent, le changement reflétera l'évolution des responsabilités de la classe. Points à noter lors de l'utilisation du SRP : 1. Une classe raisonnable ne devrait avoir qu'une seule raison pour son changement, c'est-à-dire une seule responsabilité
2. Il n'est pas judicieux d'appliquer le SRP ou d'autres principes sans signes de changement
; 3. Lorsque les exigences changent réellement, des principes tels que SRP doivent être appliqués pour refactoriser le code ;
4. L'utilisation du développement piloté par les tests nous obligera à séparer le code déraisonnable avant que la conception ne sente
5. Si vous ne pouvez pas forcer la séparation des responsabilités, l'odeur de rigidité et de fragilité deviendra très forte, alors vous devez utiliser le mode Façade ou Proxy pour refactoriser le code ; avantages SRP : éliminer le couplage et réduire la rigidité du code causée par les changements d'exigences.


Vous n'êtes pas obligé d'adhérer strictement à ces principes, et il n'y a aucune sanction religieuse en cas de violation. Mais vous devez considérer ces principes comme une sonnette d’alarme. Si l’un d’entre eux est violé, la sonnette d’alarme retentit.
-----Arthur J.Riel
(1) Toutes les données doivent être cachées à l'intérieur de la classe où elles se trouvent.
(2) Les utilisateurs d'une classe doivent s'appuyer sur l'interface partagée de la classe, mais une classe ne peut pas s'appuyer sur ses utilisateurs. p15
(3) Minimiser les messages dans le protocole de classe.
(4) Implémentez l'interface publique la plus élémentaire que toutes les classes comprennent [par exemple, les opérations de copie (copie profonde et copie superficielle), le jugement d'égalité, le contenu de sortie correct, l'analyse à partir de la description ASCII, etc.]. p16
(5) Ne mettez pas les détails d'implémentation (tels que les fonctions privées qui placent du code partagé) dans l'interface publique de la classe.
Si deux méthodes d'une classe ont un code commun, alors vous pouvez créer une fonction privée qui empêche ces codes communs.
(6) Ne perturbez pas l'interface publique d'une classe avec des éléments que les utilisateurs ne peuvent pas utiliser ou qui ne les intéressent pas. p17
(7) Il ne devrait y avoir aucun couplage entre les classes, ou uniquement des relations de couplage dérivées. Autrement dit, soit une classe n'a rien à voir avec une autre classe, soit elle utilise uniquement des opérations dans l'interface publique d'une autre classe. p18
(8) Les classes ne doivent représenter qu'une seule abstraction clé.
Toutes les classes du package doivent être fermées conjointement pour les modifications du même type de propriétés. Si un changement affecte un package, il affectera toutes les classes du package, mais n'aura aucun impact sur les autres packages
(9) Centraliser les données et les comportements associés.
Les concepteurs doivent prêter attention aux objets qui obtiennent des données d'autres objets via des opérations telles que get. Ce type de comportement implique que ce principe empirique est violé.
(10) Mettez les informations non pertinentes dans une autre classe (c'est-à-dire le comportement de ne pas communiquer entre eux). p19
Évoluez vers des dépendances stables
(11) Assurez-vous que le concept abstrait que vous modélisez est une classe, pas seulement le rôle joué par un objet. p23
(12) Répartir les fonctions du système aussi uniformément que possible dans le sens horizontal, c'est-à-dire : selon la conception, les classes de niveau supérieur doivent partager le travail de manière uniforme.
(13) Ne créez pas de classes/objets omnipotents dans votre système. Soyez particulièrement prudent avec les classes dont les noms incluent Driver, Manager, System et Susystem.
Planifier une interface plutôt que mettre en œuvre une interface.
(14) Soyez prudent avec les classes qui définissent un grand nombre de méthodes d'accès dans l'interface publique. Le grand nombre de méthodes d’accès signifie que les données et comportements pertinents ne sont pas stockés de manière centralisée.
(15) Attention aux cours qui contiennent trop de comportements qui ne communiquent pas entre eux.
Une autre manifestation de ce problème est la création de nombreuses fonctions get et set dans l'interface publique de la classe de votre application.
(16) Dans une application composée d'un modèle orienté objet qui interagit avec l'interface utilisateur, le modèle ne doit pas dépendre de l'interface, mais l'interface doit dépendre du modèle.
(17) Modéliser autant que possible en fonction du monde réel (nous violons souvent ce principe afin de respecter le principe de distribution des fonctions du système, d'éviter le principe de classe polyvalent et de placer de manière centralisée les données et les comportements associés) .
(18) Supprimez les classes inutiles de votre conception.
De manière générale, nous déclasserons cette classe en propriété.
(19) Supprimer les classes en dehors du système.
La caractéristique des classes extérieures au système est que, en termes abstraits, elles envoient uniquement des messages au domaine système mais n'acceptent pas les messages des autres classes du domaine système.
(20)Ne transformez pas les opérations en cours. Interrogez toute classe dont le nom est un verbe ou dérivé d'un verbe, en particulier une classe avec une seule action significative. Déterminez si ce comportement significatif doit être déplacé vers une classe qui existe déjà ou qui n’a pas encore été découverte.
(21) Nous introduisons souvent des classes proxy lors de la création de modèles d'analyse d'applications. Lors de la phase de conception, nous constatons souvent que de nombreux agents sont inutiles et doivent être supprimés.
(22) Essayez de réduire le nombre de collaborateurs d'une classe.
Le nombre d'autres classes utilisées par une classe doit être aussi réduit que possible.
(23) Minimisez le nombre de messages transmis entre les classes et les collaborateurs.
(24) Minimiser la quantité de collaboration entre les classes et les collaborateurs, c'est-à-dire : réduire le nombre de messages différents transmis entre les classes et les collaborateurs.
(25) Minimiser la diffusion de la classe, c'est-à-dire : réduire le produit du nombre de messages définis par la classe et du nombre de messages envoyés
(26) Si la classe contient des objets d'une autre classe , alors la classe conteneur doit être L'objet contenu envoie le message. Autrement dit : une relation d’inclusion implique toujours une relation d’usage.
(27) La plupart des méthodes définies dans une classe doivent utiliser la plupart des données membres la plupart du temps.


(28) Le nombre d'objets contenus dans une classe ne doit pas dépasser la capacité de la mémoire à court terme du développeur. Ce nombre est souvent 6.
Lorsqu'une classe contient plus de 6 données membres, vous pouvez diviser les données membres logiquement liées en un groupe, puis utiliser une nouvelle classe conteneur pour contenir ce groupe de membres.
(29) Laissez les fonctions du système être distribuées verticalement dans un système d'héritage étroit et profond.
(30) Lors de l'implémentation de contraintes sémantiques, il est préférable de les implémenter en fonction des définitions de classe. Cela conduit souvent à un débordement de classe, auquel cas les contraintes doivent être implémentées dans le comportement de la classe, généralement mais pas nécessairement dans le constructeur.
(31) Lors de l'implémentation de contraintes sémantiques dans le constructeur d'une classe, placez le test de contrainte dans le niveau d'inclusion le plus profond autorisé par le champ constructeur.
(32) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent fréquemment, alors il est préférable de les placer dans un objet tiers centralisé.
(33) Si les informations sémantiques sur lesquelles s'appuient les contraintes changent rarement, alors. il est mieux réparti entre les différentes classes impliquées dans les contraintes.
(34)Une classe doit savoir ce qu'elle contient, mais elle ne peut pas savoir qui le contient.
(35) Les objets qui partagent une portée littérale (c'est-à-dire contenus dans la même classe) ne doivent pas avoir de relation d'utilisation les uns avec les autres.
(36) L'héritage ne doit être utilisé que pour modéliser des hiérarchies de spécialisation.
(37) Les classes dérivées doivent connaître la classe de base, et les classes de base ne doivent connaître aucune information sur leurs classes dérivées.
(38) Toutes les données de la classe de base doivent être privées, n'utilisez pas de données protégées.

Les concepteurs de classe ne devraient jamais placer dans des interfaces publiques des éléments dont les utilisateurs de la classe n'ont pas besoin.
(39) En théorie, la hiérarchie d'héritage devrait être plus profonde, plus c'est profond, mieux c'est.
(40)En pratique, la profondeur de la hiérarchie successorale ne doit pas dépasser la capacité de mémoire à court terme d'une personne moyenne. Une valeur de profondeur largement acceptée est 6
(41) Toutes les classes abstraites doivent être des classes de base
(42) Toutes les classes de base doivent être des classes abstraites
(43) Placez les points communs dans les données, les comportements et/ou les interfaces aussi haut que possible dans la hiérarchie d'héritage.
(44) Si deux classes ou plus partagent des données communes (mais aucun comportement commun), alors les données communes doivent être placées dans une classe, et chaque classe qui partage ces données contient cette classe.
(45) Si deux classes ou plus ont des données et un comportement communs (c'est-à-dire des méthodes), alors chacune de ces classes doit hériter d'une classe de base commune qui représente ces données et méthodes. (46) Si deux classes ou plus partagent une interface commune (faisant référence à des messages et non à des méthodes), elles ne devraient alors hériter d'une classe de base commune que si elles doivent être utilisées de manière polymorphe. (47) L'analyse au cas par cas de l'affichage des types d'objets est généralement erronée. Dans la plupart de ces cas, les concepteurs doivent utiliser le polymorphisme.
(48) L'analyse au cas par cas de l'affichage des valeurs d'attribut est souvent erronée. Les classes doivent être découplées dans une hiérarchie d'héritage, chaque valeur d'attribut étant transformée en classe dérivée.


(49) Ne modélisez pas la sémantique dynamique d'une classe à travers des relations d'héritage. Tenter de modéliser une sémantique dynamique avec des relations sémantiques statiques entraîne un changement de type au moment de l'exécution.
(50)Ne transformez pas les objets de classe en classes dérivées. Soyez prudent avec toute classe dérivée qui n'a qu'une seule instance.
(51) Si vous pensez que vous devez créer une nouvelle classe au moment de l'exécution, prenez du recul et réalisez que vous créez des objets. Maintenant, généralisons ces objets dans une classe.
(52) Il devrait être illégal d'utiliser une méthode vide (c'est-à-dire une méthode qui ne fait rien) dans une classe dérivée pour remplacer une méthode dans la classe de base.
(53) Ne confondez pas l’inclusion facultative avec la nécessité d’un héritage. La modélisation de l'inclusion facultative comme héritage conduit à une prolifération de classes.
(54) Lors de la création de hiérarchies d'héritage, essayez de créer des frameworks réutilisables plutôt que des composants réutilisables.
(55) Si vous utilisez l'héritage multiple dans votre conception, supposez que vous avez commis une erreur. Si vous n’avez pas commis d’erreur, vous devez essayer de le prouver.
(56) Tant que l'héritage est utilisé dans la conception orientée objet, posez-vous deux questions : (1) La classe dérivée est-elle un type spécial de la chose dont elle hérite ? (2) La classe de base fait-elle partie de la classe dérivée ?
(57) Si vous trouvez plusieurs relations d'héritage dans une conception orientée objet, assurez-vous qu'aucune classe de base n'est en réalité une classe dérivée d'une autre classe de base.
(58) Dans la conception orientée objet, si vous devez choisir entre l'inclusion et l'association, veuillez choisir l'inclusion.
(59) N'utilisez pas de données globales ou de fonctions globales pour la comptabilité des objets de classe. Des variables de classe ou des méthodes de classe doivent être utilisées.
(60) Les concepteurs orientés objet ne devraient pas laisser les principes de conception physique miner leurs conceptions logiques. Cependant, nous utilisons souvent des critères de conception physique pour prendre des décisions concernant la conception logique.
(61) Ne contournez pas l'interface publique pour modifier l'état de l'objet.

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Convertissez un tableau ou un objet en chaîne JSON à l'aide de la fonction json_encode() de PHP Convertissez un tableau ou un objet en chaîne JSON à l'aide de la fonction json_encode() de PHP Nov 03, 2023 pm 03:30 PM

JSON (JavaScriptObjectNotation) est un format d'échange de données léger qui est devenu un format courant pour l'échange de données entre applications Web. La fonction json_encode() de PHP peut convertir un tableau ou un objet en chaîne JSON. Cet article explique comment utiliser la fonction json_encode() de PHP, y compris la syntaxe, les paramètres, les valeurs de retour et des exemples spécifiques. Syntaxe La syntaxe de la fonction json_encode() est la suivante : st

Utilisez la fonction __contains__() de Python pour définir l'opération de confinement d'un objet Utilisez la fonction __contains__() de Python pour définir l'opération de confinement d'un objet Aug 22, 2023 pm 04:23 PM

Utilisez la fonction __contains__() de Python pour définir l'opération de confinement d'un objet. Python est un langage de programmation concis et puissant qui fournit de nombreuses fonctionnalités puissantes pour gérer différents types de données. L'un d'eux consiste à implémenter l'opération de confinement des objets en définissant la fonction __contains__(). Cet article explique comment utiliser la fonction __contains__() pour définir l'opération de confinement d'un objet et donne un exemple de code. La fonction __contains__() est Python

Comment convertir le tableau de résultats d'une requête MySQL en objet ? Comment convertir le tableau de résultats d'une requête MySQL en objet ? Apr 29, 2024 pm 01:09 PM

Voici comment convertir un tableau de résultats de requête MySQL en objet : Créez un tableau d'objets vide. Parcourez le tableau résultant et créez un nouvel objet pour chaque ligne. Utilisez une boucle foreach pour attribuer les paires clé-valeur de chaque ligne aux propriétés correspondantes du nouvel objet. Ajoute un nouvel objet au tableau d'objets. Fermez la connexion à la base de données.

Exploration du code source : Comment les objets sont-ils appelés en Python ? Exploration du code source : Comment les objets sont-ils appelés en Python ? May 11, 2023 am 11:46 AM

Wedge Nous savons que les objets sont créés de deux manières principales, l'une via Python/CAPI et l'autre en appelant un objet de type. Pour les objets d'instance de types intégrés, les deux méthodes sont prises en charge. Par exemple, les listes peuvent être créées via [] ou list(). La première est Python/CAPI et la seconde est un objet de type appelant. Mais par exemple les objets de classes personnalisées, nous ne pouvons les créer qu'en appelant des objets de type. Si un objet peut être appelé, alors l'objet est appelable, sinon il ne l'est pas. Déterminer si un objet est appelable dépend du fait qu'une méthode est définie dans son objet de type correspondant. comme

Quelle est la différence entre les tableaux et les objets en PHP ? Quelle est la différence entre les tableaux et les objets en PHP ? Apr 29, 2024 pm 02:39 PM

En PHP, un tableau est une séquence ordonnée et les éléments sont accessibles par index ; un objet est une entité avec des propriétés et des méthodes, créée via le mot-clé new. L'accès au tableau se fait via l'index, l'accès aux objets se fait via les propriétés/méthodes. Les valeurs du tableau sont transmises et les références d'objet sont transmises.

Utilisez la fonction __le__() de Python pour définir une comparaison inférieure ou égale de deux objets Utilisez la fonction __le__() de Python pour définir une comparaison inférieure ou égale de deux objets Aug 21, 2023 pm 09:29 PM

Titre : Utilisation de la fonction __le__() de Python pour définir une comparaison inférieure ou égale de deux objets En Python, nous pouvons définir des opérations de comparaison entre des objets en utilisant des méthodes spéciales. L'une d'elles est la fonction __le__(), qui est utilisée pour définir des comparaisons inférieures ou égales. La fonction __le__() est une méthode magique en Python et est une fonction spéciale utilisée pour implémenter l'opération « inférieur ou égal ». Lorsque nous comparons deux objets en utilisant l'opérateur inférieur ou égal (<=), Python

Principes et normes pour la conception de bibliothèques de fonctions PHP Principes et normes pour la conception de bibliothèques de fonctions PHP Jun 16, 2023 am 11:37 AM

Alors que l’importance de PHP dans le développement Web continue de croître, la conception de bibliothèques de fonctions PHP est devenue l’un des enjeux clés du développement. Une bonne bibliothèque de fonctions peut non seulement améliorer l’efficacité du développement, mais également garantir la qualité et la maintenabilité du code. Par conséquent, la conception de bibliothèques de fonctions doit suivre certains principes et normes de base. 1. Une bibliothèque de fonctions ayant une bonne réutilisabilité doit être réutilisable et peut être utilisée dans différents projets. Par conséquent, les fonctions doivent être abstraites et générales et ne peuvent pas être liées à un projet ou à un scénario spécifique. 2. Facilité d'utilisation La bibliothèque de fonctions doit être facile à utiliser et transmettre des paramètres

Explication détaillée de 5 méthodes de parcours de boucle d'objets Javascript Explication détaillée de 5 méthodes de parcours de boucle d'objets Javascript Aug 04, 2022 pm 05:28 PM

Comment parcourir des objets Javascript ? L'article suivant présentera en détail cinq méthodes de traversée d'objets JS et comparera brièvement ces cinq méthodes. J'espère qu'il vous sera utile !

See all articles