Publié par

Il y a 8 années -

Temps de lecture 7 minutes

How Object-Oriented are you feeling today ? au Software Craftsmanship 2011

Software Craftsmanship Conference 2011

La dernière conférence craftsmanship en date s’est déroulée au Nord de Londres, et nous étions au rendez vous. Un programme alléchant qui promettait de nombreuses sessions hands-on de 90 minutes chacune.

Une conférence Craftsmanship n’est pas une conférence technique comme les autres. Elle attend beaucoup de ses participants. Et c’est pour ça que l’on a fait le voyage.

Tout le succès de ces conférences repose sur la qualité des échanges, on s’y rend pour remettre en question ses automatismes et tenter de devenir un peu meilleur en apprenant des autres, de leurs techniques, de leurs expériences. Cela passe inévitablement par de la pratique, en pair programming à grande échelle.

Et quand dans une salle les trois quarts des mains se lèvent lorsque l’on demande qui va programmer en TDD, et bien le vieil adage devient: tester ce n’est plus douter ! 

Si les échanges on été globalement bons dans la journée pour nous et notamment avec 3 bonnes sessions hands on – articles à suivre – nous avons été un peu déçus par la courte durée de l’ensemble, par certaines présentations qui manquaient un peu de contenu et d’apport des speakers, et par le manque de sessions de rassemblement – surement dû au fait qu’il n’y avait pas de salle pour accueillir les 150 personnes présentes. Mais nous aurions aimé voir par exemple Jason Gorman nous parler de son experience et retour Craftsmanship à Londres où il opère avec sa compagnie Codemanship.

Voici un petit retour sur les sessions auxquelles nous avons assisté, avec une première session sur la programmation objet suivie de deux autres dans un prochain billet.

How Object-Oriented are you feeling today ?

Dans cette première session, Krzysztof Jelski nous propose un exercice sur la conception orientée-objet issu ‘d’Object Calisthenics’, un essai de Jeff Bay dans ‘The ThoughtWorks Anthology, Pragmatic Bookshelf, 2008’.

Le principe est simple : écrire une petite application en respectant 9 contraintes qui, au fur et à mesure, vont diriger la conception pour la rendre plus objet.

Le kata

Les 9 contraintes sont les suivantes :

  1. Utiliser seulement 1 niveau d’indentation par méthode.
  2. Ne pas utiliser le mot clé else.
  3. Encapsuler tous les types primitifs et chaînes de caractères.
  4. Utiliser un seul ‘.’ (point) par ligne.
  5. Ne pas utiliser d’abréviations pour les noms de variable, de méthode.
  6. Conserver toutes les entités petites (50 lignes pour une classe, 10 classes par package).
  7. Ne pas utiliser de classe ayant plus de 2 variables d’instance.
  8. Encapsuler les collections dans des classes afin que le comportement d’un groupe d’objets dans la collection puisse être défini.
  9. Ne pas utiliser de getters/setters/properties. « Tell, don’t ask ».

Pour cet exercice, nous nous mettons en binôme et nous lançons façon Kata TDD (j’écris le test, tu le fais passer, tu enrichis le test, je le fais passer et ainsi de suite…).
Projet configuré, Infinitest, MoreUnit… t’as pas MoreUnit ??? Bon tant pis mais c’est dommage quand même, c’est bien pratique.

Nous enchaînons les stories sans trop de difficulté. La plupart des règles ne posent pas de réel problème au début d’un projet. Rapidement néanmoins vient la contrainte des types primitifs. Ajout d’une méthode de dépôt d’argent : la solution la plus courante est de manipuler un entier mais nous nous privons alors de la possibilité de donner du sens à ce type. Le fait de modéliser l’argent par une classe à part entière rend notre modèle, plus objet d’une part, mais surtout plus clair, plus compréhensible. En ajoutant des fonctionnalités par la suite (des opérations arithmétiques par exemple), nous enrichissons cette classe avec du comportement qui lui est propre, des contrôles. De cette manière, nous séparons bien les responsabilités des différentes classes. Il en découle, également, le respect de la contrainte 6 : conserver toutes les entités petites.

La question des responsabilités va venir également rapidement. En effet, la limitation des classes à 2 variables d’instance maximum, va véritablement orienter la conception pour séparer les responsabilités et créer des classes vraiment chargées d’une responsabilité unique. On applique ici sans véritablement s’en rendre compte le premier principe SOLID : Single Responsibility Principle. On imagine néanmoins, la difficulté d’appliquer cette contrainte sur nos applications. La démarche vaut en tout cas d’être tentée, la démarche inverse étant trop souvent la règle sur les projet.

Au niveau des autres contraintes, le fait de ne pas utiliser de getters/setters/properties permet de se concentrer sur les besoins fonctionnels. Si l’on veut avoir accès à une variable d’instance c’est en général pour répondre à un besoin fonctionnel. C’est ce besoin qui doit orienter la conception. Or, l’utilisation de getters et setters est souvent rendue nécessaire parce que la conception n’est pas objet. Un service implémente le traitement à la place de l’objet sur lequel porte le traitement et qui, lui, est anémique.

Essayez !

Malgré une durée assez courte qui ne nous a pas permis d’aborder pleinement toutes les contraintes, cette session nous a fait la démonstration qu’avec quelques contraintes bien trouvées nous nous forçons à réfléchir à l’aspect objet de notre conception ce qui permet de l’enrichir fortement. Celle-ci reflète bien le fonctionnel du projet à l’image d’une conception issue du Domain Driven Design. Les notions sont explicites, avec un nommage clair et des responsabilités bien définies, facilement testables. La taille des entités reste faible et la compréhension du code s’en trouve améliorée.

La contrainte sur les types primitifs et String est celle qui a posé le plus de problèmes pour certains, non pour des raisons de faisabilité mais pour le risque qu’elle fait peser sur les performances. Je pense pour ma part, qu’il ne faut pas écarter ce genre de conception d’office, sauf si les contraintes de performances sont importantes et nécessitent dès le démarrage de faire des concessions dans ce sens. L’encapsulation des types primitifs, string et collections permet en général par la suite d’ajouter des traitements directement sur ces classes plutôt que dans des services, ou entités extérieures. On évite souvent la duplication de code et l’appel incessant à des helper sachant tout faire. Par exemple un formatage spécifique de chaînes de caractères, des contrôles sur l’ajout ou la suppression de données dans une collection se feront directement sur la classe, allégeant ainsi considérablement les classes qui l’utilisent. Et puis créer des classes dans un langage objet, ça ne vous parait pas un peu normal ?

Je vous encourage vivement à essayer. Il n’y a ici rien de révolutionnaire au niveau de la conception elle même, mais le résultat de cette méthode par contrainte est vraiment intéressant.

Puis adaptez

Comme toute technique de ce type, il faut l’appliquer à fond pour en comprendre l’intérêt mais aussi les limites de son application ( To understand the limits of a technique, overuse it then back off ). L’objectif est, ici, à partir de quelques contraintes, de faire émerger une conception plus simple, compréhensive et évolutive. Cette conception aurait d’ailleurs pu (dû ?) être définie naturellement par un processus de conception classique mais force est de constater que ce n’est pas le cas sur la majeure partie des projets. Cependant, si l’application d’une contrainte va à l’encontre de ces objectifs de maintenabilité, il faut bien entendu faire preuve de pragmatisme et assouplir la contrainte pour ne pas obtenir un résultat inverse à celui souhaité. Le Craftsmanship repose sur la pratique et l’application de techniques, mais l’expérience acquise au fur et à mesure et le recul permettent d’arbitrer pour fournir les logiciels de qualité.

Publié par

Commentaire

4 réponses pour " How Object-Oriented are you feeling today ? au Software Craftsmanship 2011 "

  1. Publié par , Il y a 8 années

    C’est bon ça !
    Il existe un endroit où on peut voir les prochains events sur le sujet ?

  2. Publié par , Il y a 8 années

    Bonjour,

    Je découvre votre blog depuis peu et par là même mes lacunes en développement propre ; Cet article est très intéressant, je me suis moi-même demandé pourquoi les programmes en langage objet (bon, java) sur lesquels je travaillais avaient des classes qui l’étaient de moins en moins, les traitements étant faits dans des XXXXService ou XXXManager qui utilisaient des pojo via moults get et set.

    J’ai par contre du mal à imaginer votre appli sans getter ni setter… Si vous devez faire la somme de montants d’une liste, vu que vos montants sont des objets encapsulant l’entier, vous devrez bien y accéder via des getters, non ?

  3. Publié par , Il y a 8 années

    Bonjour,

    L’idée de se priver des getters, setters et properties est de faire le maximum de traitements dans les classes qui en ont la responsabilité. Le plus souvent les getters sont utilisés pour faire des traitements en dehors des objets, des services le plus souvent. Dans votre exemple, le problème vient du fait que votre classe Montant n’implémente pas la méthode add(Montant), ce qui nécessite de faire un get sur l’entier pour l’ajouter à un autre. Avec une conception où votre liste est une classe à par entière, elle définit une méthode sum(), par exemple, qui va parcourir la liste des montant et les ajouter dans un Montant résultat via add(Montant). Pas besoin de get ici.

    Les setters, eux, posent problème car on se retrouve rapidement dans un état où l’objet en cours de modification n’est pas valide tant qu’un ensemble de set n’a pas été réalisé. L’objectif, ici, est de s’assurer que l’objet est à tout moment dans un état valide, via des constructeurs (et l’utilisation de builders si besoin), de méthodes dédiées au merge de données par exemple.

    Nous pouvons néanmoins avoir besoin de getter/properties dans le cas d’utilisation de ValueObjects pour des besoins de transferts ou de présentation.

    Cordialement.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Xebian, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.