
La beauté des motifs de design
Description
Introduction au livre
Les secrets de gestion de la qualité du code chez Google révélés
Chez Google, où la qualité du code était une priorité, on allait jusqu'à exiger la correction de la moindre erreur de ponctuation dans les commentaires du code. Grâce à ce contrôle strict de la qualité du code, les coûts de maintenance du projet ont été considérablement réduits.
Ce livre, compilation de telles expériences, fournit des instructions détaillées sur la manière d'écrire du code de haute qualité selon cinq aspects : les paradigmes orientés objet, les principes de conception, les règles de codage, les techniques de refactorisation et les modèles de conception, sur la base de plus de 200 exemples de projets réels.
Chez Google, où la qualité du code était une priorité, on allait jusqu'à exiger la correction de la moindre erreur de ponctuation dans les commentaires du code. Grâce à ce contrôle strict de la qualité du code, les coûts de maintenance du projet ont été considérablement réduits.
Ce livre, compilation de telles expériences, fournit des instructions détaillées sur la manière d'écrire du code de haute qualité selon cinq aspects : les paradigmes orientés objet, les principes de conception, les règles de codage, les techniques de refactorisation et les modèles de conception, sur la base de plus de 200 exemples de projets réels.
- Vous pouvez consulter un aperçu du contenu du livre.
Aperçu
indice
Préface du traducteur xiii
Revue du lecteur bêta xiv
Début XVI
CHAPITRE 1 Aperçu 1
1.1 Pourquoi apprendre la conception de code ? 1
1.1.1 Écriture de code de haute qualité 2 / 1.1.2 Gestion du développement de code complexe 2
1.1.3 Compétences de base en programmation 4 / 1.1.4 Compétences requises pour le développement de carrière 5
__1.1.5 Réflexion 5
1.2 Méthode d'évaluation de la qualité du code 6
1.2.1 Maintenabilité 8 / 1.2.2 Lisibilité 9 / 1.2.3 Extensibilité 10 / 1.2.4 Flexibilité 10
1.2.5 Concision 11 / 1.2.6 Réutilisabilité 11 / 1.2.7 Testabilité 12 / 1.2.8 Réflexion 12
1.3 Comment écrire du code de haute qualité 12
1.3.1 Programmation orientée objet 13 / 1.3.2 Principes de conception 13 / 1.3.3 Modèles de conception 14
1.3.4 Règles de codage 15 / 1.3.5 Techniques de refactoring 15 / 1.3.6 Réflexion 17
1.4 Comment éviter la surdimensionnement 18
1.4.1 L'objectif initial de la conception de code est d'améliorer la qualité du code.
1.4.2 Le principe de la conception de code est qu'il y a un problème en amont et une solution en aval.
1.4.3 Les scénarios d'application de la conception de code doivent être appliqués aux codes complexes 19
__1.4.4 La refactorisation continue peut efficacement prévenir la surconception 20
__1.4.5 Ne discutez pas de la conception du code en dehors de scénarios spécifiques 20
__1.4.6 Penser 21
CHAPITRE 2 Paradigme de la programmation orientée objet 23
2.1 Qu'est-ce que la programmation orientée objet ? 23
__2.1.1 Programmation orientée objet et langages de programmation orientés objet 23
2.1.2 Langages de programmation orientés objet qui ne sont pas strictement définis 25
__2.1.3 Analyse orientée objet et conception orientée objet 26
__2.1.4 Notes sur UML 27
__2.1.5 Réflexion 28
2.2 Pourquoi l'encapsulation, l'abstraction, l'héritage et le polymorphisme émergent-ils ? 28
__2.2.1 Encapsulation 28 / 2.2.2 Abstraction 31 / 2.2.3 Héritage 33 /
__2.2.4 Polymorphisme 35 / 2.2.5 Réflexions 39
2.3 Comment réaliser une analyse orientée objet, une conception orientée objet et une programmation orientée objet 40
__2.3.1 Exemple d'introduction et d'analyse de la difficulté 40
__2.3.2 Comment effectuer une analyse orientée objet 41
__2.3.3 Méthodes de conception orientées objet 45
__2.3.4 Comment programmer de manière orientée objet 53
__2.3.5 Réflexion 55
2.4 Différences entre la programmation orientée objet, la programmation procédurale et la programmation fonctionnelle 55
__2.4.1 Programmation procédurale 55
__2.4.2 Comparaison de la programmation orientée objet et de la programmation procédurale 59
__2.4.3 Programmation fonctionnelle 62
__2.4.4 Comparaison de la programmation orientée objet et de la programmation fonctionnelle 69
__2.4.5 Réflexion 69
2.5 Cela ressemble à de la programmation orientée objet, mais il s'agit en réalité de programmation procédurale. 70
__2.5.1 Abus des méthodes getter et setter 70
__2.5.2 Utilisation abusive des variables globales et des méthodes globales 74
__2.5.3 Définition d'une classe par séparation des données et des méthodes 77
__2.5.4 Réflexion 79
2.6 L’approche de développement traditionnelle, fondée sur un modèle de domaine inadéquat, viole-t-elle les principes de la programmation orientée objet ? 79
__2.6.1 Méthodes de développement traditionnelles basées sur un modèle de domaine inadéquat 80
__2.6.2 Méthode de développement DDD basée sur un modèle de domaine riche 82
__2.6.3 Comparaison de deux méthodes de développement 83
__2.6.4 Pourquoi les méthodes de développement traditionnelles basées sur des modèles de domaine médiocres sont-elles si largement utilisées ? 90
__2.6.5 Scénario d'application 91 du développement DDD basé sur des modèles de domaine riches
__2.6.6 Réflexion 92
2.7 Classes abstraites et interfaces 93
__2.7.1 Définition et différences entre les classes abstraites et les interfaces 93
__2.7.2 Signification des classes abstraites et des interfaces 97
__2.7.3 Implémentations factices de classes abstraites et d'interfaces 100
__2.7.4 Scénarios d'application des classes abstraites et des interfaces 102
__2.7.5 Réflexion 102
2.8 Programmation basée sur une interface :
Dois-je définir une interface pour chaque classe ? 102
__2.8.1 Différentes manières de comprendre les interfaces 103
__2.8.2 Mettons en pratique la philosophie de conception 104
__2.8.3 Comment prévenir l'utilisation abusive des interfaces ? 108
__2.8.4 Réflexion 109
2.9 Synthèse sur héritage 109
__2.9.1 Pourquoi l'héritage est déprécié 109
__2.9.2 Avantages de la composition par rapport à l'héritage 112
__2.9.3 Choisir entre la composition et l'héritage 114
__2.9.4 Réflexion 115
CHAPITRE 3 PRINCIPES DE CONCEPTION 117
3.1 Principe de responsabilité unique 117
3.1.1 Définition et interprétation du principe de responsabilité unique 117
3.1.2 Comment déterminer si une classe a une responsabilité unique 118
3.1.3 Si les responsabilités de la classe sont décrites aussi précisément que possible 121
__3.1.4 Penser 123
3.2 Principe ouvert-fermé 123
__3.2.1 Ouvert lors de l'extension, fermé lors de la modification 123
3.2.2 La modification du code viole-t-elle le principe ouvert/fermé ? 129
3.2.3 Comment parvenir à l'ouverture lors de l'extension et à la fermeture lors de la modification 131
3.2.4 Comment appliquer avec souplesse le principe ouvert-fermé à un projet 133
__3.2.5 Réflexion 134
3.3 Principe de substitution de Liskov 134
3.3.1 Définition du principe de substitution de Liskov 134
3.3.2 Différences entre le principe de substitution de Liskov et le polymorphisme 136
3.3.3 Anti-modèles qui violent le principe de substitution de Liskov 137
__3.3.4 Réflexion 139
3.4 Principe de ségrégation des interfaces 139
3.4.1 Interface en tant qu'ensemble d'API ou de fonctions 139
3.4.2 Interfaces sous forme d'API ou de fonction unique 141
3.4.3 Interfaces en programmation orientée objet 142
__3.4.4 Réflexion 149
3.5 Principe d'inversion de dépendance 149
3.5.1 Inversion de contrôle 150 / 3.5.2 Injection de dépendances 152 / 3.5.3 Cadre d'injection de dépendances 153
3.5.4 Principe d'inversion de dépendance 154 / 3.5.5 Réflexion 155
3.6 Le principe KISS et le principe YAGNI 155
3.6.1 Définition et interprétation du principe KISS 155
3.6.2 Moins de lignes de code ne signifient pas un code plus simple 156
3.6.3 Un code complexe ne viole pas nécessairement le principe KISS 158
3.6.4 Comment écrire du code qui respecte le principe KISS 160
3.6.5 Différences entre les principes YAGNI et KISS 160
__3.6.6 Réflexion 161
3.7 Principe DRY 161
3.7.1 Duplication de la logique du code 161 / 3.7.2 Duplication fonctionnelle (sémantique) 164
3.7.3 Duplication de l'exécution du code 165 / 3.7.4 Réutilisation du code 167
__3.7.5 Réflexion 169
3.8 LoD 169
3.8.1 Réflexions sur la forte cohésion et le faible couplage 169
__3.8.2 Définition de LoD 171
__3.8.3 Définition, interprétation et premier exemple de code 171
__3.8.4 Définition, interprétation et deuxième exemple de code 174
__3.8.5 Réflexion 177
CHAPITRE 4 Règles de codage 179
4.1 Dénomination et annotation 179
4.1.1 Noms longs et noms courts 179
4.1.2 Simplification de la dénomination à l'aide d'informations contextuelles 180
4.1.3 Unification des noms à l'aide d'un glossaire métier 180
4.1.4 La dénomination doit être précise mais abstraite 181
4.1.5 Éléments à inclure dans les commentaires 181
__4.1.6 Plus de commentaires, ce n'est pas une bonne chose 183
__4.1.7 Réflexion 183
4.2 Style de code 184
4.2.1 Taille appropriée des classes et des fonctions 184
4.2.2 Longueur appropriée d'une ligne 185
4.2.3 Séparation des blocs de code par des lignes vides 185
__4.2.4 Indenter de 4 espaces ou Indenter de 2 espaces 185
4.2.5 Où doit être placée l'entretoise d'ouverture ? 186
__4.2.6 Commande de membre de classe 186
__4.2.7 Réflexion 187
4.3 Conseils de codage 187
4.3.1 Modularisation du code complexe 187 / 4.3.2 Gestion des paramètres de fonction 188
4.3.3 Suppression des paramètres d'indicateur des fonctions 189 / 4.3.4 Suppression du code profondément imbriqué 191
4.3.5 Variables explicatives 194 / 4.3.6 Réflexions 195
CHAPITRE 5 Techniques de refactorisation 197
5.1 Les quatre éléments de la refactorisation : objectif, cible, moment et méthode 197
5.1.1 Objectif de la refactorisation 197 / 5.1.2 Cible de la refactorisation 199
5.1.3 Quand refactoriser 199 / 5.1.4 Comment refactoriser 200
__5.1.5 Réflexion 201
5.2 Tests unitaires 201
5.2.1 À propos des tests unitaires 201
__5.2.2 Pourquoi écrire du code de test unitaire ? 204
__5.2.3 Comment concevoir des tests unitaires 206
__5.2.4 Pourquoi les tests unitaires sont difficiles à écrire 209
__5.2.5 Réflexion 210
5.3 Testabilité du code 210
5.3.1 Comment écrire du code testable 210
__5.3.2 Code non testable 220
__5.3.3 Réflexion 222
5.4 Découplage 223
__5.4.1 Pourquoi le découplage est important 223
5.4.2 Détermination de la nécessité du découplage du code 223
__5.4.3 Méthode de découplage de code 224
__5.4.4 Réflexion 227
5.5 Exemple de refactorisation 227
5.5.1 Exigences et contexte de développement du générateur d'identifiants 228
__5.5.2 Implémentation du code de niveau utilisable 228
__5.5.3 Comment trouver les problèmes de qualité du code 230
__5.5.4 Refactorisation pour une meilleure lisibilité 232
__5.5.5 Refactorisation pour améliorer la testabilité du code 234
__5.5.6 Refactorisation pour l'écriture de code de tests unitaires 236
__5.5.7 Refactorisation pour la gestion des exceptions 239
__5.5.8 Réflexion 251
CHAPITRE 6 : MODÈLES DE CONCEPTION GÉNÉRATIONNELS 253
6.1 Modèle Singleton (1) 253
6.1.1 Définition du modèle Singleton 253 / 6.1.2 Implémentation du modèle Singleton 254
6.1.3 Application du modèle Singleton 259 / 6.1.4 Inconvénients du modèle Singleton 263
6.1.5 Alternatives au modèle Singleton 266 / 6.1.6 Réflexions 268
6.2 Modèle Singleton (2) 268
6.2.1 Unicité du modèle Singleton 268
__6.2.2 Motif Singleton à fil uniquement 269
__6.2.3 Modèle Singleton dans un environnement de cluster 270
__6.2.4 Modèle multi-instance 272
__6.2.5 Réflexion 273
6.3 Modèle d'usine (1) 273
6.3.1 Modèle d'usine simple 274 / 6.3.2 Modèle de méthode d'usine 278
6.3.3 Modèle de fabrication abstrait 281 / 6.3.4 Application du modèle de fabrication 283
__6.3.5 Réflexion 283
6.4 Modèle d'usine (2) 284
6.4.1 Différences entre le conteneur DI et le modèle d'usine 284
__6.4.2 Fonctionnalités principales du conteneur DI 284
6.4.3 Conception et implémentation du conteneur DI 287
__6.4.4 Réflexion 292
Modèle de constructeur 6.5 293
6.5.1 Création d'objets à l'aide de constructeurs 293
6.5.2 Définition des variables membres à l'aide de méthodes setter 295
6.5.3 Validation des paramètres à l'aide du modèle Builder 296
__6.5.4 Application du modèle Builder dans Guava 299
6.5.5 Différences entre le modèle de construction et le modèle d'usine 301
__6.5.6 Réflexion 301
6.6 Modèle prototype 302
6.6.1 Définition du modèle prototype 302
6.6.2 Application du modèle prototype 302
6.6.3 Mise en œuvre du modèle prototype 306
__6.6.4 Réflexion 310
CHAPITRE 7 Modèles de conception structurelle 313
7.1 Modèle de proxy 313
__7.1.1 Modèle de proxy basé sur une interface 313
__7.1.2 Modèle de proxy basé sur l'héritage 316
__7.1.3 Proxy dynamique basé sur la réflexion 317
__7.1.4 Comment utiliser le modèle de proxy 318
__7.1.5 Penser 320
7.2 Modèle Décorateur : Analyse des principes de conception fondamentaux de la bibliothèque Java IO 320
7.2.1 Utilisations inhabituelles de la bibliothèque d'E/S Java 320
7.2.2 Conception basée sur l'héritage 322
7.2.3 Planification de la conception basée sur le modèle du décorateur 323
__7.2.4 Réflexion 328
7.3 Modèle d'adaptateur 328
__7.3.1 Adaptateurs de classe et adaptateurs d'objet 328
7.3.2 Application du modèle d'adaptateur 330
__7.3.3 Journalisation Java et modèle d'adaptateur 336
__7.3.4 Modèle d'emballage 338
__7.3.5 Réflexion 342
7.4 Modèle de pont 343
7.4.1 Définition du modèle de pont 343
__7.4.2 Résolution de l'héritage explosif avec le modèle de pont 343
__7.4.3 Réflexion 344
7.5 Motif de façade 344
7.5.1 Modèle de façade et conception d'interface 345
7.5.2 Application du modèle de façade : amélioration de l’ergonomie de l’interface 346
7.5.3 Application du modèle de façade : amélioration des performances de l’interface 346
7.5.4 Application du modèle de façade : résolution des problèmes de transaction 346
__7.5.5 Réflexion 348
7.6 Motif complexe 348
__7.6.1 Arborescence de répertoires basée sur le modèle composite 348
7.6.2 Arbre humain basé sur des modèles complexes 353
__7.6.3 Réflexion 356
Modèle 356, poids mouche 7,7
7.7.1 Application des schémas de poids mouche aux parties d'échecs 356
7.7.2 Application du modèle Flyweight dans un éditeur de texte 359
__7.7.3 Application du modèle Flyweight à l'entier 362 de Java
__7.7.4 Application du modèle Flyweight à la chaîne de caractères 367 de Java
__7.7.5 Différences entre le modèle Flyweight, le modèle Singleton, le cache et le pool d'objets 368
__7.7.6 Réflexion 369
CHAPITRE 8 : MODÈLES DE CONCEPTION COMPORTEMENTALE 371
8.1 Modèle d'observateur 371
8.1.1 Définition du modèle d'observateur 371
8.1.2 Implémentation du modèle Observateur 372
8.1.3 Signification du modèle de l'observateur 373
8.1.4 Application du modèle de l'observateur 376
8.1.5 Modèle d'observateur asynchrone non bloquant 377
__8.1.6 Framework EventBus 379
8.1.7 Implémentation du framework EventBus à partir de zéro 382
__8.1.8 Réflexion 388
8.2 Modèle de méthode de gabarit (1) 388
8.2.1 Définition et implémentation du modèle de méthode de modèle 388
8.2.2 Le rôle du modèle de conception Template Method : Réutilisation 390
8.2.3 Le rôle du modèle de méthode Template : extension 392
__8.2.4 Réflexion 395
8.3 Modèle de méthode de gabarit (2) 396
8.3.1 Principes et implémentation des rappels 396
__8.3.2 Classe JdbcTemplate 398
__8.3.3 méthode setClickListener() 401
__8.3.4 méthode addShutdownHook() 402
8.3.5 Différences entre les modèles de méthodes de gabarit et les rappels 404
__8.3.6 Réflexion 405
8.4 Modèles stratégiques 405
8.4.1 Définition et mise en œuvre du modèle stratégique 405
8.4.2 Remplacement des décisions à embranchements par des modèles stratégiques 408
8.4.3 Tri du contenu des fichiers à l'aide de modèles de stratégie 410
8.4.4 Mauvaise utilisation du modèle stratégique 417
__8.4.5 Réflexion 417
8.5 Modèle de chaîne de responsabilité 417
8.5.1 Définition et mise en œuvre du modèle de chaîne de responsabilité 417
8.5.2 Filtrage des mots sensibles basé sur le modèle de chaîne de responsabilité 423
__8.5.3 Filtre de servlet basé sur le modèle de chaîne de responsabilité 426
__8.5.4 Modèle de chaîne de responsabilité et intercepteurs de Spring 430
__8.5.5 Modèle de chaîne de responsabilité et plugins MyBatis 432
__8.5.6 Réflexion 439
8.6 Modèle d'état 439
8.6.1 Qu'est-ce qu'une machine à états finis ? 439
8.6.2 Implémentation d'une machine à états finis à l'aide de méthodes de décision par embranchement 442
8.6.3 Implémentation d'une machine à états à l'aide de la méthode de recherche par table 443
8.6.4 Implémentation d'une machine à états avec le modèle d'état 446
__8.6.5 Réflexion 451
8.7 Modèle d'itérateur (1) 451
8.7.1 Définition et implémentation du modèle Itérateur 451
__8.7.2 Méthode d'itération de collection 454
__8.7.3 Problème d'itérateur 456
8.7.4 Résolution du problème de l'itérateur 458
__8.7.5 Réflexion 463
8.8 Modèle d'itérateur (2) 464
__8.8.1 Itérateur prenant en charge la fonctionnalité d'instantané 464
8.8.2 Réflexions sur la conception à partir de plusieurs copies 466
8.8.3 Réflexions sur la conception temporelle 466
__8.8.4 Réflexion 470
8.9 Profil des visiteurs 470
8.9.1 Processus de dérivation du modèle visiteur 470
__8.9.2 Double Dispatch 481
__8.9.3 Réflexion 484
8.10 Motif Memento 485
8.10.1 Définition et implémentation du modèle Memento 485
8.10.2 Optimisation du temps et de l'espace 489
__8.10.3 Réflexion 490
Modèle de commande 8.11 490
8.11.1 Définition du modèle de commande 490
8.11.2 Application des modèles de commandes aux serveurs de jeux mobiles 491
8.11.3 Différences entre les modèles de commandement et de stratégie 494
__8.11.4 Réflexion 494
8.12 Modèle d'interprète 494
8.12.1 Définition du modèle d'interprétation 494
8.12.2 Évaluation d'expressions avec le modèle d'interprétation 495
8.12.3 Développement d'un moteur de règles avec le modèle d'interpréteur 499
__8.12.4 Réflexion 502
8.13 Modèle d'arbitre 502
8.13.1 Définition et mise en œuvre du modèle de médiateur 503
8.13.2 Différences entre le modèle du médiateur et le modèle de l'observateur 504
__8.13.3 Réflexion 505
Recherche 506
Revue du lecteur bêta xiv
Début XVI
CHAPITRE 1 Aperçu 1
1.1 Pourquoi apprendre la conception de code ? 1
1.1.1 Écriture de code de haute qualité 2 / 1.1.2 Gestion du développement de code complexe 2
1.1.3 Compétences de base en programmation 4 / 1.1.4 Compétences requises pour le développement de carrière 5
__1.1.5 Réflexion 5
1.2 Méthode d'évaluation de la qualité du code 6
1.2.1 Maintenabilité 8 / 1.2.2 Lisibilité 9 / 1.2.3 Extensibilité 10 / 1.2.4 Flexibilité 10
1.2.5 Concision 11 / 1.2.6 Réutilisabilité 11 / 1.2.7 Testabilité 12 / 1.2.8 Réflexion 12
1.3 Comment écrire du code de haute qualité 12
1.3.1 Programmation orientée objet 13 / 1.3.2 Principes de conception 13 / 1.3.3 Modèles de conception 14
1.3.4 Règles de codage 15 / 1.3.5 Techniques de refactoring 15 / 1.3.6 Réflexion 17
1.4 Comment éviter la surdimensionnement 18
1.4.1 L'objectif initial de la conception de code est d'améliorer la qualité du code.
1.4.2 Le principe de la conception de code est qu'il y a un problème en amont et une solution en aval.
1.4.3 Les scénarios d'application de la conception de code doivent être appliqués aux codes complexes 19
__1.4.4 La refactorisation continue peut efficacement prévenir la surconception 20
__1.4.5 Ne discutez pas de la conception du code en dehors de scénarios spécifiques 20
__1.4.6 Penser 21
CHAPITRE 2 Paradigme de la programmation orientée objet 23
2.1 Qu'est-ce que la programmation orientée objet ? 23
__2.1.1 Programmation orientée objet et langages de programmation orientés objet 23
2.1.2 Langages de programmation orientés objet qui ne sont pas strictement définis 25
__2.1.3 Analyse orientée objet et conception orientée objet 26
__2.1.4 Notes sur UML 27
__2.1.5 Réflexion 28
2.2 Pourquoi l'encapsulation, l'abstraction, l'héritage et le polymorphisme émergent-ils ? 28
__2.2.1 Encapsulation 28 / 2.2.2 Abstraction 31 / 2.2.3 Héritage 33 /
__2.2.4 Polymorphisme 35 / 2.2.5 Réflexions 39
2.3 Comment réaliser une analyse orientée objet, une conception orientée objet et une programmation orientée objet 40
__2.3.1 Exemple d'introduction et d'analyse de la difficulté 40
__2.3.2 Comment effectuer une analyse orientée objet 41
__2.3.3 Méthodes de conception orientées objet 45
__2.3.4 Comment programmer de manière orientée objet 53
__2.3.5 Réflexion 55
2.4 Différences entre la programmation orientée objet, la programmation procédurale et la programmation fonctionnelle 55
__2.4.1 Programmation procédurale 55
__2.4.2 Comparaison de la programmation orientée objet et de la programmation procédurale 59
__2.4.3 Programmation fonctionnelle 62
__2.4.4 Comparaison de la programmation orientée objet et de la programmation fonctionnelle 69
__2.4.5 Réflexion 69
2.5 Cela ressemble à de la programmation orientée objet, mais il s'agit en réalité de programmation procédurale. 70
__2.5.1 Abus des méthodes getter et setter 70
__2.5.2 Utilisation abusive des variables globales et des méthodes globales 74
__2.5.3 Définition d'une classe par séparation des données et des méthodes 77
__2.5.4 Réflexion 79
2.6 L’approche de développement traditionnelle, fondée sur un modèle de domaine inadéquat, viole-t-elle les principes de la programmation orientée objet ? 79
__2.6.1 Méthodes de développement traditionnelles basées sur un modèle de domaine inadéquat 80
__2.6.2 Méthode de développement DDD basée sur un modèle de domaine riche 82
__2.6.3 Comparaison de deux méthodes de développement 83
__2.6.4 Pourquoi les méthodes de développement traditionnelles basées sur des modèles de domaine médiocres sont-elles si largement utilisées ? 90
__2.6.5 Scénario d'application 91 du développement DDD basé sur des modèles de domaine riches
__2.6.6 Réflexion 92
2.7 Classes abstraites et interfaces 93
__2.7.1 Définition et différences entre les classes abstraites et les interfaces 93
__2.7.2 Signification des classes abstraites et des interfaces 97
__2.7.3 Implémentations factices de classes abstraites et d'interfaces 100
__2.7.4 Scénarios d'application des classes abstraites et des interfaces 102
__2.7.5 Réflexion 102
2.8 Programmation basée sur une interface :
Dois-je définir une interface pour chaque classe ? 102
__2.8.1 Différentes manières de comprendre les interfaces 103
__2.8.2 Mettons en pratique la philosophie de conception 104
__2.8.3 Comment prévenir l'utilisation abusive des interfaces ? 108
__2.8.4 Réflexion 109
2.9 Synthèse sur héritage 109
__2.9.1 Pourquoi l'héritage est déprécié 109
__2.9.2 Avantages de la composition par rapport à l'héritage 112
__2.9.3 Choisir entre la composition et l'héritage 114
__2.9.4 Réflexion 115
CHAPITRE 3 PRINCIPES DE CONCEPTION 117
3.1 Principe de responsabilité unique 117
3.1.1 Définition et interprétation du principe de responsabilité unique 117
3.1.2 Comment déterminer si une classe a une responsabilité unique 118
3.1.3 Si les responsabilités de la classe sont décrites aussi précisément que possible 121
__3.1.4 Penser 123
3.2 Principe ouvert-fermé 123
__3.2.1 Ouvert lors de l'extension, fermé lors de la modification 123
3.2.2 La modification du code viole-t-elle le principe ouvert/fermé ? 129
3.2.3 Comment parvenir à l'ouverture lors de l'extension et à la fermeture lors de la modification 131
3.2.4 Comment appliquer avec souplesse le principe ouvert-fermé à un projet 133
__3.2.5 Réflexion 134
3.3 Principe de substitution de Liskov 134
3.3.1 Définition du principe de substitution de Liskov 134
3.3.2 Différences entre le principe de substitution de Liskov et le polymorphisme 136
3.3.3 Anti-modèles qui violent le principe de substitution de Liskov 137
__3.3.4 Réflexion 139
3.4 Principe de ségrégation des interfaces 139
3.4.1 Interface en tant qu'ensemble d'API ou de fonctions 139
3.4.2 Interfaces sous forme d'API ou de fonction unique 141
3.4.3 Interfaces en programmation orientée objet 142
__3.4.4 Réflexion 149
3.5 Principe d'inversion de dépendance 149
3.5.1 Inversion de contrôle 150 / 3.5.2 Injection de dépendances 152 / 3.5.3 Cadre d'injection de dépendances 153
3.5.4 Principe d'inversion de dépendance 154 / 3.5.5 Réflexion 155
3.6 Le principe KISS et le principe YAGNI 155
3.6.1 Définition et interprétation du principe KISS 155
3.6.2 Moins de lignes de code ne signifient pas un code plus simple 156
3.6.3 Un code complexe ne viole pas nécessairement le principe KISS 158
3.6.4 Comment écrire du code qui respecte le principe KISS 160
3.6.5 Différences entre les principes YAGNI et KISS 160
__3.6.6 Réflexion 161
3.7 Principe DRY 161
3.7.1 Duplication de la logique du code 161 / 3.7.2 Duplication fonctionnelle (sémantique) 164
3.7.3 Duplication de l'exécution du code 165 / 3.7.4 Réutilisation du code 167
__3.7.5 Réflexion 169
3.8 LoD 169
3.8.1 Réflexions sur la forte cohésion et le faible couplage 169
__3.8.2 Définition de LoD 171
__3.8.3 Définition, interprétation et premier exemple de code 171
__3.8.4 Définition, interprétation et deuxième exemple de code 174
__3.8.5 Réflexion 177
CHAPITRE 4 Règles de codage 179
4.1 Dénomination et annotation 179
4.1.1 Noms longs et noms courts 179
4.1.2 Simplification de la dénomination à l'aide d'informations contextuelles 180
4.1.3 Unification des noms à l'aide d'un glossaire métier 180
4.1.4 La dénomination doit être précise mais abstraite 181
4.1.5 Éléments à inclure dans les commentaires 181
__4.1.6 Plus de commentaires, ce n'est pas une bonne chose 183
__4.1.7 Réflexion 183
4.2 Style de code 184
4.2.1 Taille appropriée des classes et des fonctions 184
4.2.2 Longueur appropriée d'une ligne 185
4.2.3 Séparation des blocs de code par des lignes vides 185
__4.2.4 Indenter de 4 espaces ou Indenter de 2 espaces 185
4.2.5 Où doit être placée l'entretoise d'ouverture ? 186
__4.2.6 Commande de membre de classe 186
__4.2.7 Réflexion 187
4.3 Conseils de codage 187
4.3.1 Modularisation du code complexe 187 / 4.3.2 Gestion des paramètres de fonction 188
4.3.3 Suppression des paramètres d'indicateur des fonctions 189 / 4.3.4 Suppression du code profondément imbriqué 191
4.3.5 Variables explicatives 194 / 4.3.6 Réflexions 195
CHAPITRE 5 Techniques de refactorisation 197
5.1 Les quatre éléments de la refactorisation : objectif, cible, moment et méthode 197
5.1.1 Objectif de la refactorisation 197 / 5.1.2 Cible de la refactorisation 199
5.1.3 Quand refactoriser 199 / 5.1.4 Comment refactoriser 200
__5.1.5 Réflexion 201
5.2 Tests unitaires 201
5.2.1 À propos des tests unitaires 201
__5.2.2 Pourquoi écrire du code de test unitaire ? 204
__5.2.3 Comment concevoir des tests unitaires 206
__5.2.4 Pourquoi les tests unitaires sont difficiles à écrire 209
__5.2.5 Réflexion 210
5.3 Testabilité du code 210
5.3.1 Comment écrire du code testable 210
__5.3.2 Code non testable 220
__5.3.3 Réflexion 222
5.4 Découplage 223
__5.4.1 Pourquoi le découplage est important 223
5.4.2 Détermination de la nécessité du découplage du code 223
__5.4.3 Méthode de découplage de code 224
__5.4.4 Réflexion 227
5.5 Exemple de refactorisation 227
5.5.1 Exigences et contexte de développement du générateur d'identifiants 228
__5.5.2 Implémentation du code de niveau utilisable 228
__5.5.3 Comment trouver les problèmes de qualité du code 230
__5.5.4 Refactorisation pour une meilleure lisibilité 232
__5.5.5 Refactorisation pour améliorer la testabilité du code 234
__5.5.6 Refactorisation pour l'écriture de code de tests unitaires 236
__5.5.7 Refactorisation pour la gestion des exceptions 239
__5.5.8 Réflexion 251
CHAPITRE 6 : MODÈLES DE CONCEPTION GÉNÉRATIONNELS 253
6.1 Modèle Singleton (1) 253
6.1.1 Définition du modèle Singleton 253 / 6.1.2 Implémentation du modèle Singleton 254
6.1.3 Application du modèle Singleton 259 / 6.1.4 Inconvénients du modèle Singleton 263
6.1.5 Alternatives au modèle Singleton 266 / 6.1.6 Réflexions 268
6.2 Modèle Singleton (2) 268
6.2.1 Unicité du modèle Singleton 268
__6.2.2 Motif Singleton à fil uniquement 269
__6.2.3 Modèle Singleton dans un environnement de cluster 270
__6.2.4 Modèle multi-instance 272
__6.2.5 Réflexion 273
6.3 Modèle d'usine (1) 273
6.3.1 Modèle d'usine simple 274 / 6.3.2 Modèle de méthode d'usine 278
6.3.3 Modèle de fabrication abstrait 281 / 6.3.4 Application du modèle de fabrication 283
__6.3.5 Réflexion 283
6.4 Modèle d'usine (2) 284
6.4.1 Différences entre le conteneur DI et le modèle d'usine 284
__6.4.2 Fonctionnalités principales du conteneur DI 284
6.4.3 Conception et implémentation du conteneur DI 287
__6.4.4 Réflexion 292
Modèle de constructeur 6.5 293
6.5.1 Création d'objets à l'aide de constructeurs 293
6.5.2 Définition des variables membres à l'aide de méthodes setter 295
6.5.3 Validation des paramètres à l'aide du modèle Builder 296
__6.5.4 Application du modèle Builder dans Guava 299
6.5.5 Différences entre le modèle de construction et le modèle d'usine 301
__6.5.6 Réflexion 301
6.6 Modèle prototype 302
6.6.1 Définition du modèle prototype 302
6.6.2 Application du modèle prototype 302
6.6.3 Mise en œuvre du modèle prototype 306
__6.6.4 Réflexion 310
CHAPITRE 7 Modèles de conception structurelle 313
7.1 Modèle de proxy 313
__7.1.1 Modèle de proxy basé sur une interface 313
__7.1.2 Modèle de proxy basé sur l'héritage 316
__7.1.3 Proxy dynamique basé sur la réflexion 317
__7.1.4 Comment utiliser le modèle de proxy 318
__7.1.5 Penser 320
7.2 Modèle Décorateur : Analyse des principes de conception fondamentaux de la bibliothèque Java IO 320
7.2.1 Utilisations inhabituelles de la bibliothèque d'E/S Java 320
7.2.2 Conception basée sur l'héritage 322
7.2.3 Planification de la conception basée sur le modèle du décorateur 323
__7.2.4 Réflexion 328
7.3 Modèle d'adaptateur 328
__7.3.1 Adaptateurs de classe et adaptateurs d'objet 328
7.3.2 Application du modèle d'adaptateur 330
__7.3.3 Journalisation Java et modèle d'adaptateur 336
__7.3.4 Modèle d'emballage 338
__7.3.5 Réflexion 342
7.4 Modèle de pont 343
7.4.1 Définition du modèle de pont 343
__7.4.2 Résolution de l'héritage explosif avec le modèle de pont 343
__7.4.3 Réflexion 344
7.5 Motif de façade 344
7.5.1 Modèle de façade et conception d'interface 345
7.5.2 Application du modèle de façade : amélioration de l’ergonomie de l’interface 346
7.5.3 Application du modèle de façade : amélioration des performances de l’interface 346
7.5.4 Application du modèle de façade : résolution des problèmes de transaction 346
__7.5.5 Réflexion 348
7.6 Motif complexe 348
__7.6.1 Arborescence de répertoires basée sur le modèle composite 348
7.6.2 Arbre humain basé sur des modèles complexes 353
__7.6.3 Réflexion 356
Modèle 356, poids mouche 7,7
7.7.1 Application des schémas de poids mouche aux parties d'échecs 356
7.7.2 Application du modèle Flyweight dans un éditeur de texte 359
__7.7.3 Application du modèle Flyweight à l'entier 362 de Java
__7.7.4 Application du modèle Flyweight à la chaîne de caractères 367 de Java
__7.7.5 Différences entre le modèle Flyweight, le modèle Singleton, le cache et le pool d'objets 368
__7.7.6 Réflexion 369
CHAPITRE 8 : MODÈLES DE CONCEPTION COMPORTEMENTALE 371
8.1 Modèle d'observateur 371
8.1.1 Définition du modèle d'observateur 371
8.1.2 Implémentation du modèle Observateur 372
8.1.3 Signification du modèle de l'observateur 373
8.1.4 Application du modèle de l'observateur 376
8.1.5 Modèle d'observateur asynchrone non bloquant 377
__8.1.6 Framework EventBus 379
8.1.7 Implémentation du framework EventBus à partir de zéro 382
__8.1.8 Réflexion 388
8.2 Modèle de méthode de gabarit (1) 388
8.2.1 Définition et implémentation du modèle de méthode de modèle 388
8.2.2 Le rôle du modèle de conception Template Method : Réutilisation 390
8.2.3 Le rôle du modèle de méthode Template : extension 392
__8.2.4 Réflexion 395
8.3 Modèle de méthode de gabarit (2) 396
8.3.1 Principes et implémentation des rappels 396
__8.3.2 Classe JdbcTemplate 398
__8.3.3 méthode setClickListener() 401
__8.3.4 méthode addShutdownHook() 402
8.3.5 Différences entre les modèles de méthodes de gabarit et les rappels 404
__8.3.6 Réflexion 405
8.4 Modèles stratégiques 405
8.4.1 Définition et mise en œuvre du modèle stratégique 405
8.4.2 Remplacement des décisions à embranchements par des modèles stratégiques 408
8.4.3 Tri du contenu des fichiers à l'aide de modèles de stratégie 410
8.4.4 Mauvaise utilisation du modèle stratégique 417
__8.4.5 Réflexion 417
8.5 Modèle de chaîne de responsabilité 417
8.5.1 Définition et mise en œuvre du modèle de chaîne de responsabilité 417
8.5.2 Filtrage des mots sensibles basé sur le modèle de chaîne de responsabilité 423
__8.5.3 Filtre de servlet basé sur le modèle de chaîne de responsabilité 426
__8.5.4 Modèle de chaîne de responsabilité et intercepteurs de Spring 430
__8.5.5 Modèle de chaîne de responsabilité et plugins MyBatis 432
__8.5.6 Réflexion 439
8.6 Modèle d'état 439
8.6.1 Qu'est-ce qu'une machine à états finis ? 439
8.6.2 Implémentation d'une machine à états finis à l'aide de méthodes de décision par embranchement 442
8.6.3 Implémentation d'une machine à états à l'aide de la méthode de recherche par table 443
8.6.4 Implémentation d'une machine à états avec le modèle d'état 446
__8.6.5 Réflexion 451
8.7 Modèle d'itérateur (1) 451
8.7.1 Définition et implémentation du modèle Itérateur 451
__8.7.2 Méthode d'itération de collection 454
__8.7.3 Problème d'itérateur 456
8.7.4 Résolution du problème de l'itérateur 458
__8.7.5 Réflexion 463
8.8 Modèle d'itérateur (2) 464
__8.8.1 Itérateur prenant en charge la fonctionnalité d'instantané 464
8.8.2 Réflexions sur la conception à partir de plusieurs copies 466
8.8.3 Réflexions sur la conception temporelle 466
__8.8.4 Réflexion 470
8.9 Profil des visiteurs 470
8.9.1 Processus de dérivation du modèle visiteur 470
__8.9.2 Double Dispatch 481
__8.9.3 Réflexion 484
8.10 Motif Memento 485
8.10.1 Définition et implémentation du modèle Memento 485
8.10.2 Optimisation du temps et de l'espace 489
__8.10.3 Réflexion 490
Modèle de commande 8.11 490
8.11.1 Définition du modèle de commande 490
8.11.2 Application des modèles de commandes aux serveurs de jeux mobiles 491
8.11.3 Différences entre les modèles de commandement et de stratégie 494
__8.11.4 Réflexion 494
8.12 Modèle d'interprète 494
8.12.1 Définition du modèle d'interprétation 494
8.12.2 Évaluation d'expressions avec le modèle d'interprétation 495
8.12.3 Développement d'un moteur de règles avec le modèle d'interpréteur 499
__8.12.4 Réflexion 502
8.13 Modèle d'arbitre 502
8.13.1 Définition et mise en œuvre du modèle de médiateur 503
8.13.2 Différences entre le modèle du médiateur et le modèle de l'observateur 504
__8.13.3 Réflexion 505
Recherche 506
Image détaillée

Dans le livre
On dit souvent qu'il faut prêter attention à la qualité du code et ne pas négliger la phase de conception du code avant de l'écrire.
Un code sous-dimensionné n'est pas bon, mais un code surdimensionné ne l'est pas non plus.
Dans mes expériences professionnelles passées, j'ai eu de nombreux collègues, notamment des ingénieurs ayant peu d'expérience en développement, qui avaient tendance à surdimensionner leur code et à abuser des modèles de conception.
Ils consacrent beaucoup de temps à la conception de leur code avant même de commencer à coder.
Pour des exigences simples ou un code simple, il est courant d'appliquer divers modèles de conception au cours du processus de développement, dans l'espoir que le code sera plus flexible et constituera une base solide pour les développements futurs.
Cependant, une conception excessive ne fait qu'accroître la complexité du code, car les exigences pourraient ne pas changer par la suite.
Il nous faut donc aborder la question de la surconception, et notamment celle de la surutilisation des modèles de conception, tels que les paradigmes de programmation orientée objet, les principes de conception, les conventions de codage et le refactoring.
--- p.18
Cependant, la plupart des programmeurs commencent souvent à écrire du code juste après avoir effectué mentalement ou sous forme de simples croquis l'analyse et la conception orientées objet, et ils optimisent et refactorisent souvent le code au fur et à mesure qu'ils l'écrivent.
À l'inverse, même si vous consacrez beaucoup de temps à l'analyse et à la conception orientées objet et que vous dessinez des diagrammes de classes et des diagrammes UML solides avant d'écrire la moindre ligne de code, il est impossible de définir tous les détails et toutes les interactions en une seule fois.
Lorsque vous écrivez du code, vous devez encore le retourner, le refactoriser et recommencer.
En définitive, le développement logiciel est essentiellement un processus d'itération continue, de correction de bugs, de recherche de problèmes, de résolution de problèmes et de refactorisation continue.
Il est important de comprendre qu'il est impossible de réaliser une étape à la lettre et de passer ensuite à la suivante.
--- p.55
Il existe une manière plus compréhensible d'expliquer le principe de Liskov : la conception par contrat.
Lors de la conception d'une sous-classe, celle-ci doit respecter les règles de comportement de la superclasse.
La superclasse définit les règles de comportement de la fonction, et la sous-classe peut modifier la logique d'implémentation interne de la fonction, mais ne peut pas modifier les règles de comportement originales de la fonction.
Les règles comportementales abordées ici comprennent ce que la fonction déclare implémenter, les règles d'entrée, de sortie, d'exceptions et toutes les descriptions de cas particuliers listées dans les commentaires.
En fait, la relation entre superclasse et sous-classe mentionnée ici pourrait être remplacée par la relation entre interface et classe d'implémentation.
--- p.137
Le modèle Factory est utilisé pour créer des objets de types différents mais apparentés, tels qu'un groupe de sous-classes qui héritent de la même superclasse ou interface, où le type d'objet à créer est déterminé par des paramètres prédéfinis.
En revanche, le modèle de conception Builder crée des objets du même type avec une complexité élevée, mais définit des paramètres optionnels ou crée d'autres objets par le biais de la personnalisation.
La différence entre les deux modèles peut être facilement comprise grâce à un exemple classique.
Lorsqu'un client entre dans un restaurant et passe commande, le modèle « usine » peut être utilisé pour créer une variété de plats tels que des pizzas, des hamburgers et des salades en fonction de la sélection du client, et le modèle « constructeur » peut être utilisé pour créer une pizza avec diverses garnitures sélectionnées par le client, telles que du fromage, des tomates et du bacon.
--- p.301
Lors de l'application du modèle Memento, si l'objet à sauvegarder est relativement volumineux ou si la fréquence de sauvegarde est élevée, la mémoire occupée par l'instantané sera relativement importante et le temps requis pour la sauvegarde et la restauration sera relativement long.
Comment résoudre ce problème ? / Chaque scénario d'application a sa propre solution optimale.
Par exemple, l'exemple que nous avons examiné dans la section 8.10.1 a implémenté la fonctionnalité d'annulation à l'aide du modèle Memento, mais ne prenait en charge que l'annulation séquentielle.
Autrement dit, lorsque vous utilisez la fonction Annuler, vous ne pouvez annuler que le dernier texte saisi, et vous n'êtes pas obligé de passer à l'étape suivante et d'annuler le texte précédemment saisi.
Dans ce cas, au lieu de stocker l'intégralité du texte dans un instantané pour économiser de la mémoire, vous pouvez enregistrer séparément de petites quantités d'informations.
Lorsque vous obtenez la longueur du texte que vous avez saisi lors de la prise d'un instantané, vous pouvez utiliser une méthode pour supprimer cette longueur du texte original.
Un code sous-dimensionné n'est pas bon, mais un code surdimensionné ne l'est pas non plus.
Dans mes expériences professionnelles passées, j'ai eu de nombreux collègues, notamment des ingénieurs ayant peu d'expérience en développement, qui avaient tendance à surdimensionner leur code et à abuser des modèles de conception.
Ils consacrent beaucoup de temps à la conception de leur code avant même de commencer à coder.
Pour des exigences simples ou un code simple, il est courant d'appliquer divers modèles de conception au cours du processus de développement, dans l'espoir que le code sera plus flexible et constituera une base solide pour les développements futurs.
Cependant, une conception excessive ne fait qu'accroître la complexité du code, car les exigences pourraient ne pas changer par la suite.
Il nous faut donc aborder la question de la surconception, et notamment celle de la surutilisation des modèles de conception, tels que les paradigmes de programmation orientée objet, les principes de conception, les conventions de codage et le refactoring.
--- p.18
Cependant, la plupart des programmeurs commencent souvent à écrire du code juste après avoir effectué mentalement ou sous forme de simples croquis l'analyse et la conception orientées objet, et ils optimisent et refactorisent souvent le code au fur et à mesure qu'ils l'écrivent.
À l'inverse, même si vous consacrez beaucoup de temps à l'analyse et à la conception orientées objet et que vous dessinez des diagrammes de classes et des diagrammes UML solides avant d'écrire la moindre ligne de code, il est impossible de définir tous les détails et toutes les interactions en une seule fois.
Lorsque vous écrivez du code, vous devez encore le retourner, le refactoriser et recommencer.
En définitive, le développement logiciel est essentiellement un processus d'itération continue, de correction de bugs, de recherche de problèmes, de résolution de problèmes et de refactorisation continue.
Il est important de comprendre qu'il est impossible de réaliser une étape à la lettre et de passer ensuite à la suivante.
--- p.55
Il existe une manière plus compréhensible d'expliquer le principe de Liskov : la conception par contrat.
Lors de la conception d'une sous-classe, celle-ci doit respecter les règles de comportement de la superclasse.
La superclasse définit les règles de comportement de la fonction, et la sous-classe peut modifier la logique d'implémentation interne de la fonction, mais ne peut pas modifier les règles de comportement originales de la fonction.
Les règles comportementales abordées ici comprennent ce que la fonction déclare implémenter, les règles d'entrée, de sortie, d'exceptions et toutes les descriptions de cas particuliers listées dans les commentaires.
En fait, la relation entre superclasse et sous-classe mentionnée ici pourrait être remplacée par la relation entre interface et classe d'implémentation.
--- p.137
Le modèle Factory est utilisé pour créer des objets de types différents mais apparentés, tels qu'un groupe de sous-classes qui héritent de la même superclasse ou interface, où le type d'objet à créer est déterminé par des paramètres prédéfinis.
En revanche, le modèle de conception Builder crée des objets du même type avec une complexité élevée, mais définit des paramètres optionnels ou crée d'autres objets par le biais de la personnalisation.
La différence entre les deux modèles peut être facilement comprise grâce à un exemple classique.
Lorsqu'un client entre dans un restaurant et passe commande, le modèle « usine » peut être utilisé pour créer une variété de plats tels que des pizzas, des hamburgers et des salades en fonction de la sélection du client, et le modèle « constructeur » peut être utilisé pour créer une pizza avec diverses garnitures sélectionnées par le client, telles que du fromage, des tomates et du bacon.
--- p.301
Lors de l'application du modèle Memento, si l'objet à sauvegarder est relativement volumineux ou si la fréquence de sauvegarde est élevée, la mémoire occupée par l'instantané sera relativement importante et le temps requis pour la sauvegarde et la restauration sera relativement long.
Comment résoudre ce problème ? / Chaque scénario d'application a sa propre solution optimale.
Par exemple, l'exemple que nous avons examiné dans la section 8.10.1 a implémenté la fonctionnalité d'annulation à l'aide du modèle Memento, mais ne prenait en charge que l'annulation séquentielle.
Autrement dit, lorsque vous utilisez la fonction Annuler, vous ne pouvez annuler que le dernier texte saisi, et vous n'êtes pas obligé de passer à l'étape suivante et d'annuler le texte précédemment saisi.
Dans ce cas, au lieu de stocker l'intégralité du texte dans un instantané pour économiser de la mémoire, vous pouvez enregistrer séparément de petites quantités d'informations.
Lorsque vous obtenez la longueur du texte que vous avez saisi lors de la prise d'un instantané, vous pouvez utiliser une méthode pour supprimer cette longueur du texte original.
--- p.489
Avis de l'éditeur
Améliorez la qualité de votre code grâce à la programmation orientée objet, aux principes de conception, aux conventions de codage, au refactoring et aux modèles de conception.
À mesure que les développeurs acquièrent de l'expérience, ils sont de plus en plus motivés par le désir d'améliorer la qualité de leur code.
Malheureusement, les services de développement de nombreuses entreprises sont pressés de créer chaque fonctionnalité et de respecter les délais.
Si le code que vous avez écrit fonctionne tout simplement, vous n'avez ni le temps ni l'espace pour y revenir.
Mais lorsqu'on doit maintenir un code créé à la hâte de cette manière, on finit par être frustré et on a envie de tout supprimer et de tout réécrire.
Alors, comment écrire du code de haute qualité ? Ayant travaillé dans un environnement de développement (Google) qui réduit considérablement les coûts de maintenance grâce à un contrôle strict de la qualité du code, l’auteur recommande d’acquérir d’abord des connaissances théoriques en conception de code.
La connaissance des théories de conception de code contribue à améliorer la maintenabilité, la lisibilité, l'extensibilité, la flexibilité, la concision, la réutilisabilité et la testabilité du code.
Le chapitre 1 du livre définit ce qu'est un code de haute qualité et vous montre comment éviter la surconception.
Le chapitre 2 présente la programmation orientée objet, qui est la base des principes de conception et des modèles de conception, et le chapitre 3 présente des principes de conception importants tels que le principe SOLID, le principe KISS, le principe YAGNI, le principe DRY et le principe LoD.
Au chapitre 4, vous découvrirez les conventions de codage, notamment la dénomination des fichiers, les commentaires, le style de code et des conseils de programmation. Le chapitre 5 aborde les quatre éléments du refactoring : les tests unitaires, la testabilité du code et le découplage. Vous y apprendrez des techniques de refactoring illustrées par des exemples.
Les chapitres 6, 7 et 8 présentent 22 modèles de conception, répartis en trois catégories : création, structure et comportement.
Le chapitre 6 présente les modèles de conception de création, notamment le modèle singleton, le modèle usine, le modèle constructeur et le modèle prototype, et le chapitre 7 présente les modèles de conception structurels, notamment le modèle proxy, le modèle décorateur, le modèle adaptateur, le modèle pont, le modèle façade, le modèle composite et le modèle poids mouche.
Le chapitre 8 présente les modèles de conception comportementaux, notamment le modèle Observateur, le modèle Méthode de modèle, le modèle Stratégie, le modèle Chaîne de responsabilité, le modèle État, le modèle Itérateur, le modèle Visiteur, le modèle Memento, le modèle Commande, le modèle Interprète et le modèle Médiateur.
Bien que la majeure partie du code de ce livre soit écrite en Java, le contenu et les explications ne sont pas spécifiques à un langage et peuvent être lus par toute personne utilisant n'importe quel langage de programmation.
Recommandé à tous les développeurs qui souhaitent améliorer leurs compétences en programmation.
À mesure que les développeurs acquièrent de l'expérience, ils sont de plus en plus motivés par le désir d'améliorer la qualité de leur code.
Malheureusement, les services de développement de nombreuses entreprises sont pressés de créer chaque fonctionnalité et de respecter les délais.
Si le code que vous avez écrit fonctionne tout simplement, vous n'avez ni le temps ni l'espace pour y revenir.
Mais lorsqu'on doit maintenir un code créé à la hâte de cette manière, on finit par être frustré et on a envie de tout supprimer et de tout réécrire.
Alors, comment écrire du code de haute qualité ? Ayant travaillé dans un environnement de développement (Google) qui réduit considérablement les coûts de maintenance grâce à un contrôle strict de la qualité du code, l’auteur recommande d’acquérir d’abord des connaissances théoriques en conception de code.
La connaissance des théories de conception de code contribue à améliorer la maintenabilité, la lisibilité, l'extensibilité, la flexibilité, la concision, la réutilisabilité et la testabilité du code.
Le chapitre 1 du livre définit ce qu'est un code de haute qualité et vous montre comment éviter la surconception.
Le chapitre 2 présente la programmation orientée objet, qui est la base des principes de conception et des modèles de conception, et le chapitre 3 présente des principes de conception importants tels que le principe SOLID, le principe KISS, le principe YAGNI, le principe DRY et le principe LoD.
Au chapitre 4, vous découvrirez les conventions de codage, notamment la dénomination des fichiers, les commentaires, le style de code et des conseils de programmation. Le chapitre 5 aborde les quatre éléments du refactoring : les tests unitaires, la testabilité du code et le découplage. Vous y apprendrez des techniques de refactoring illustrées par des exemples.
Les chapitres 6, 7 et 8 présentent 22 modèles de conception, répartis en trois catégories : création, structure et comportement.
Le chapitre 6 présente les modèles de conception de création, notamment le modèle singleton, le modèle usine, le modèle constructeur et le modèle prototype, et le chapitre 7 présente les modèles de conception structurels, notamment le modèle proxy, le modèle décorateur, le modèle adaptateur, le modèle pont, le modèle façade, le modèle composite et le modèle poids mouche.
Le chapitre 8 présente les modèles de conception comportementaux, notamment le modèle Observateur, le modèle Méthode de modèle, le modèle Stratégie, le modèle Chaîne de responsabilité, le modèle État, le modèle Itérateur, le modèle Visiteur, le modèle Memento, le modèle Commande, le modèle Interprète et le modèle Médiateur.
Bien que la majeure partie du code de ce livre soit écrite en Java, le contenu et les explications ne sont pas spécifiques à un langage et peuvent être lus par toute personne utilisant n'importe quel langage de programmation.
Recommandé à tous les développeurs qui souhaitent améliorer leurs compétences en programmation.
SPÉCIFICATIONS DES PRODUITS
- Date d'émission : 26 mai 2023
Nombre de pages, poids, dimensions : 528 pages | 1 014 g | 188 × 245 × 26 mm
- ISBN13 : 9791192987101
- ISBN10 : 1192987101
Vous aimerez peut-être aussi
카테고리
Langue coréenne
Langue coréenne