nov. 28 2010

[ASP.NET] Design Patterns et Best Pratices - Partie 3 : Les Patterns du Gang of Four

Category: ASP.NET | Design PatternsNicolas Esprit @ 17:48

Dans ce troisième billet de la série sur les Design Patterns et Best Pratices en ASP.NET, nous allons voir comment sont décrits et formalisés les Design Patterns du Gang of Four, examiner les groupements de ceux-ci, pour enfin voir comment choisir et appliquer un Pattern. Pour rappel, vous pouvez consulter les deux précédents billets :

Comment lire un Design Pattern ?

Dans le livre "Design Patterns: Elements of Reusable Object-Oriented Software" du Gang of Four, chaque modèle est présenté dans un format bien précis que l'on pourrait appeller un "template de description de pattern". L'idée derrière ce template est de permettre au lecteur de déchiffrer un Pattern et d'en apprendre davantage sur les problèmes qu'il est censé résoudre. La bible des Patterns décrit chaque modèle en utilisant le template suivant :

  • Nom du Pattern et classification : le nom est important dans le sens où il contribue à constituer un vocabulaire commun pour la communauté de développeurs. La classification, c'est à dire le groupe, définit le travail du Pattern, je reviendrais sur cette notion plus loin.
  • But : cette section décrit les problèmes que le modèle vise à résoudre et pourquoi il est utile.
  • Aussi connu sous : décrit les autre appelations utilisées pour ce Pattern.
  • Motivation : décrit un scénario de problème et la façon d'utiliser le Pattern pour le résoudre.
  • Application : énumère les situations où il est avantageux d'appliquer le Pattern.
  • Structure : représentation graphique du modèle, y compris les collaborations et les relations entre les objets. Un diagramme UML est généralement utilisé.
  • Participants : tous les objets impliqués dans de Pattern.
  • Collaborations : indique comment les participants travaillent ensemble pour former le Pattern.
  • Conséquences : répertorie tous les avantages et les inconvénients causés par la mise en œuvre du Pattern.
  • Mise en œuvre : décrit les pièges possibles et les Best Pratices lors de la mise en œuvre du Pattern.
  • Exemple de code : montre une implémentation du Pattern dans un langage en particulier.
  • Utilisations connues : une section bien utile qui décrit des implémentations du Pattern dans des applications réelles.
  • Patterns connexes : liste d'autres Patterns qui collaborent ou bien travaillent avec ce Pattern.

Comme vous pouvez le constater, les Patterns sont livrés avec une mine d'information permettant de bien les comprendre, de connaître les avantages et inconvénients lors de leur utilisation, d'avoir des exemples concrets d'application mais aussi plein d'autres choses.  Dans les prochains billets, je ne vais pas reprendre toutes les informations du livre du GoF, mais fournirais au minimum le nom et la classification du Pattern, un diagramme UML, ainsi qu'un exemple de code en C# appliqué à un problème ASP.NET.


Les groupes des Design Patterns du Gof

La bible présente 23 Patterns. Chaque Pattern relève de l'un de ces trois groupes:

  • Les Patterns de construction (Creational Patterns)
  • Les Patterns structuraux (Structural Patterns)
  • Les Patterns comportementaux (Behavioral Patterns)

Les Patterns de construction

Les Patterns de ce groupe définissent comment réaliser l'instanciation et la configuration des classes et des objets. Ils visent ainsi à respecter les principes que nous avons vu dans le second billet, à savoir : le principe SOLID Single Responsability et le principe de conception Separation of Concerns. Pour résumer, ces Patterns visent à :

  • Abstraire le processus d'instanciation.
  • Rendre indépendant de la façon dont les objets sont créés, composés, assemblés, représentés.
  • Encapsuler la connaissance de la classe concrète qui instancie.
  • Cacher ce qui est créé, qui crée, comment et quand.

Voici la liste de ces Patterns avec un bref descriptif :

  • Abstract Factory : fournit une interface pour créer des familles d'objets apparentés.
  • Factory : permet à une classe de déléguer la responsabilité de créer un objet valide.
  • Builder : permet de construire différentes versions d'un objet en séparant la construction de l'objet lui-même. A ne pas confondre avec le Pattern Factory.
  • Prototype: permet de créer de nouveaux objets à partir d'objets existants, par copie ou clonage. ce Pattern permet ainsi d'élaborer de nouveaux prototypes qui pourront être réutilisés plus tard.
  • Singleton: permet une classe d'être instanciée une seule et unique fois en fournissant ainsi un seul point d'accès.

Les Patterns structuraux

Les Patterns de ce groupe définissent comment organiser les classes d'une application dans une structure plus large, sépérant l'interface de l'implémentation. Pour résumer :

  • Ces Patterns visent à structurer la façon dont les objets sont assemblés
  • Ces Patterns sont complémentaires les uns des autres

Voici la liste de ces Patterns avec un bref descriptif :

  • Adapter : permet à des classes d'interface incompatibles à être utilisées ensembles. Permet en gros de rendre un objet conforme à un autre.
  • Bridge : sépare une abstraction de sa mise en œuvre, permettant ainsi à l'abstraction et son implémentation de varier indépendamment les unes des autres.
  • Composite : permet à un groupe d'objets représentant des hiérarchies d'être traités de la même façon qu'une seule instance d'un objet.
  • Decorator : peut englober dynamiquement une classe et étendre son comportement. Ce Pattern permet d'ajouter des services à un objet.
  • Façade : fournit une interface simple et contrôle l'accès à une série d'interfaces complexes et de sous-systèmes. Il permet donc de cacher une structure complexe.
  • Flyweight : fournit un moyen de partager des données entre de nombreuses petites classes d'une manière efficace.
  • Proxy : fournit un espace réservé à une classe plus complexe qu'il est coûteux d'instancier.

Les Patterns comportementaux

Les Patterns de ce groupe définissent comment organiser les objets pour que ceux-ci collaborent (distribution des responsabilités) et expliquent le fonctionnement des algorithmes impliqués. Les caractéristiques de ce groupe est d'encapsuler un comportement complexe et abstrait, permettant ainsi à des systèmes complexes d'être facilement compréhensibles. Ces Patterns comportementaux décrivent donc :

  • Des algorithmes
  • Des comportements entre objets
  • Des formes de communication entre objet

Voici la liste de ces Patterns avec un bref descriptif :

  • Chain of Responsibility : permet à un nombre quelconque de classes d'essayer de répondre à une requête sans connaître les possibilités des autres classes sur cette requête. Cela permet de diminuer le couplage entre objets
  • Commande : encapsule une méthode comme un objet et sépare l'exécution d'une commande de son invocateur.
  • Interpreter : indique comment évaluer phrases dans une langage. Ce Pattern définit la grammaire de ce langage et utilise celle-ci pour interpréter des états dans ce langage.
  • Iterator : permet de naviguer dans une collection d'une manière formalisée.
  • Mediator : définit un objet qui permet la communication entre deux autres objets à leur insu.
  • Memento : permet de restaurer un objet à son état précédent.
  • Observer : définit la manière dont une ou plusieurs classes peuvent être alertées à un changement dans une autre classe.
  • State : utilisé pour représenter les différents états d'un objet. Il permet à un objet de changer partiellement d'état et donc son comportement à l'exécution.
  • Strategy : plus vaste que le pattern State, permet de choisir un algorithme adapté au contexte.
  • Template Method : définit le squelette d'un algorithme à l'aide d'opérations abstraites dont le comportement concret se trouvera dans les sous-classes, qui implémenteront ces opérations.
  • Visitor : permet une séparation précise entre données et traitements.

Si vous n'êtes pas familliers des Designs Patterns, vous devez maintenant comprendre (tout du moins avoir une idée générale) du rôle de chacun des Patterns du GoF. Evidemment, un bref descriptif est loin d'être suffisant comparé à une étude détaillée avec diagramme UML, exemple de code et exemple d'utilisation sur un cas concret. Il est important de comprendre comment s'y prendre pour choisir et appliquer le Pattern le plus approprié pour votre problème.


Comment choisir et appliquer un Design Pattern ?

Comme nous venons de le voir avec la description des groupes de Patterns du GoF, vous pouvez choisir parmi de nombreux modèles. Alors comment faire pour identifier celui qui est le plus approprié à votre problème ? Pour savoir quel Pattern utiliser et la façon de l'appliquer à votre problème spécifique, il est important de comprendre ces lignes directrices :

  • Vous ne pouvez appliquer des Patterns sans les connaître. La première étape importante consiste à élargir vos connaissances et d'étudier les Patterns à la fois sous leur forme abstraite et concrète. Vous pouvez mettre en œuvre un Pattern de différentes manières. Plus vous en voyez les différentes implémentations, plus vous comprendrez le but de celui-ci et la façon dont un Pattern unique peut avoir des implémentations différentes.
  • Avez-vous vraiment besoin d'introduire la complexité d'un Design Pattern ? Comme je l'ai indiqué dans le précédent billet, il est commun pour beaucoup de développeurs d'essayer d'utiliser un Pattern pour résoudre tous les problèmes qu'ils étudient. Rappelez-vous le principe KISS: Keep It Simple, Stupid !
  • Généralisez votre problème, identifiez les problèmes que vous affrontez de la façon la plus abstraite possible. Regardez comment le but de chaque modèle et le principe est écrit, et voyez si votre problème correspond au problème d'un Pattern en particulier. Rappelez-vous que les modèles de conception sont des solutions de haut niveau, essayez de faire abstraction de votre problème, et ne vous focalisez pas sur les détails de votre problème spécifique.
  • Regardez les Patterns de même nature et figurant dans le même groupe. Tout simplement parce que vous avez utilisé un modèle avant, ce n'est pas une raison de se dire qu'il sera toujours le meilleur choix pour résoudre un problème.
  • Encapsulez ce qui varie. Regardez ce qui sera susceptible de changer avec votre application. Si vous savez qu'un algorithme va changer au fil du temps, trouvez un Pattern qui vous aidera à le changer sans affecter le reste de votre application. En règle générale, lorsqu'on développe une application, il faut toujours penser évolutivité et maintenance.
  • Après avoir choisi un Pattern, veillez à ce que vous utilisez son nom dans votre implémentation. En utilisant le vocabulaire commun cela rendra votre code plus lisible et compréhensible pour les autres développeurs.

 

Pour les Design Patterns, il n'y a pas de solution miracle pour les maîtriser. Plus vous en savez sur chacun d'eux, mieux vous serez à même de les appliquer. Et même si vous avez de l'expérience avec eux, pensez à relire le but de chacun des Patterns pour vous rafraîchir la mémoire lorsque vous avez un problème et êtes à la recherche d'une solution.

A présent, si j'ai bien fait mon boulot, vous devriez avoir une compréhension de la manière de lire et de déchiffrer un Design Pattern, un aperçu de la liste des 23 Patterns du GoF, et quelques notions sur la façon de choisir et d'appliquer ceux-ci. Pour aider la compréhension, rien ne vaut l'exemple et l'étude de cas pratique. Le prochain billet sera donc dédié à cela, avec le refactoring d'une application ASP.NET et l'utilisation de différents Patterns.

Tags: , ,

Commentaires

1.
pingback topsy.com says:

Pingback from topsy.com

Twitter Trackbacks for
        
        [ASP.NET] Design Patterns et Best Pratices - Partie 3 : Les Patterns du Gang of Four
        [nicolasesprit.com]
        on Topsy.com

2.
trackback Nicolas Esprit says:

[ASP.NET] Design Patterns et Best Pratices - Partie 4 : Cas pratique et Refactoring

[ASP.NET] Design Patterns et Best Pratices - Partie 4 : Cas pratique et Refactoring

Les commentaires sont clos