septembre 2009Monthly :

L’APMM, un modèle de maturité de processus? Vraiment?

Voici un article qui concerne notre “sujet de l’heure” à Pyxis, la maturité : Agility at Scale: Become as Agile as You Can Be. Par Scott W. Ambler lui-même, produit par IBM.

Dans cet article, le focus est sur la complexité des processus nécessaires pour répondre à des besoins divers en terme de taille de projet, distribution, risque, de niveau de gouvernance, et 4 autres critères. Au final, on n’y parle pas beaucoup de maturité de processus, mais plutôt de contextes d’application : “However, whereas the goal of the CMMI is to provide a framework for software process improvement, the goal of the Agile Process Maturity Model (APMM) is much more modest — it merely strives to define a framework that can be used to put the myriad agile processes into context.”

Les 3 niveaux de “maturité” sont définis selon les besoins du projet. Est-ce que le niveau de complexité du projet (calculé par 8 critères) exige qu’on couvre le développement logiciel, ou la durée de vie complète d’un projet, ou même la gestion de l’entreprise dans son ensemble?

  1. Niveau 1? Utilisez Scrum, XP et/ou Agile Modeling
  2. Niveau 2? Utilisez RUP, OpenUP, DSDM ( warning : “[RUP] can be instantiated anywhere from a very agile form to a very traditional form as your situation warrants”)
  3. Niveau 3? Explorez RUP, EUP!!!

Je me pose évidemment plusieurs questions. Clairement, je ne vois pas de modèle de mesure de maturité d’une équipe, ni même d’une implémentation de processus, mais bien un support pour faire un choix de méthode pour une situation X. Avez-vous vu d’autres modèles de maturité des processus Agiles? À quelles questions devrait répondre un tel modèle?

De mon côté, j’aimerais bien savoir comment détecter le niveau de maturité d’une équipe pour savoir le niveau d’auto-organisation auquel je dois m’attendre de leur part, le niveau de gouvernance nécessaire au projet, le nombre d’experts (coachs agiles, coachs techniques, architectes) à qui je dois avoir recours pour leur venir en aide. Dans le cadre d’une transition, j’aimerais savoir à quel point il faut être directif, à quel point il faut les bousculer dans leur confort. Mais c’est évidemment en dehors de la portée de ce modèle. C’est même complètement autre chose.

Le mot “maturité” est-il trop général? De quoi ai-je besoin?

Il y a 2 listes synthèse intéressantes qui méritent également un regard à cet article :

  • Pour savoir “si une équipe est agile”, Scott propose ses 5 critères. Peut-être les avez-vous déjà vu quelque part?
  • Les 5 stratégies à appliquer pour accroître vos chances d’avoir du succès dans l’amélioration de votre processus.

Why I choose to invest in clean code

Lately there is a lot of talk about “Clean Code”. This is in part due to Robert Martin’s recent book by the same name. I’ve heard people come up with idealistic reasons to embrace clean code practices. That all well and good, but when you’re face with a team who does not share your conviction, this can be difficult.

Why should I invest in clean up code if I cannot keep the whole of the code pristine?

Well I continue to write clean code and to re-pass the broom over the same floors I have previously swept because if I dont it will deteriorate into a real bordello.

I continue to clean up because every effort I make to figure some tangled mess out is an effort I do not want to repeat later. The two hours I spend trying to figure out the purpose of a dozen poorly-named classes are hours I do not want to re-live. The next time I pass through this code I want my previous insights to jump out at me, not hide behind the same mess I dug through last time.

I continue to clean up along my path because I hope that the next person (however clean-conscience they may or may not be) does not get slowed down by the previous mess. This person is my team-mate, and the success of my current commitments is dependent on them. Anything I can do to save them wasted time benefits me.

I continue to write clean code and clean up the problems that cross my path because that same team-mate may waste my precious time asking me questions that I could otherwise have answered directly in the code.

This seemingly futile exercise in clean up is all geared at saving me wasted time on a daily basis.

Why do I chose to invest in clean code? Because I’m lazy.

Agile du point de vue d’un PMP

Hier, le 15 septembre, François Beauregard, fondateur et président de Pyxis, présentait Agile vu du point de vue d’un PMP au PMI de Montréal, à un groupe d’une cinquantaine de professionnels.

Son but :  présenter les différences fondamentales entre l’approche Agile et celle du PMI, sougliner comment une entreprise peut passer à une approche Agile, avec tout ce que cela implique en termes de gestion du changement, et enfin fournir des éléments de réflexion pour que les PMP puissent mettre en oeuvre concrètement des améliorations dans leurs projets.

Retrouvez la présentation “Agile du point de vue d’un PMP”

Les métriques d’ingénierie logicielle dans une entreprise agile

Depuis ce matin, un étudiant au doctorat de l’UQAM est parmi nous. M. Oualid Ktata va passer quelques jours par semaine chez Pyxis pour les deux prochaines sessions.  Il réalisera les travaux de l’étude en assistant et observant les façons de faire sur différents projets.  Pour réaliser ces travaux en collaboration avec l’UQAM, nous avons obtenu une aide financière du MITACS.  Voici comment a été stipulé le but de l’exercice :

“Le stage a pour but de décrire et modéliser les processus d’une entreprise de développement de logiciel fondée sur les valeurs de l’agilité et de proposer un modèle de mesures adapté à ces valeurs et répondant aux besoins de gestion de la qualité et de la productivité.  Il vise à développer des approches « d’ingénierie logicielle agile » et à pouvoir les documenter de façon adéquate au moyen de métriques et de mesures statistiques.

Les avantages escomptés pour cette entreprise qui a déjà atteint un certain niveau de maturité dans l’agilité sont de pouvoir par la suite procéder à des activités d’amélioration de la qualité et de la productivité et d’offrir des activités de formation sur « l’ingénierie logicielle agile ».”

Les bénéfices spécifiques attendus sont de plus d’un niveau:
Niveau individuel : Grâce aux données collectées, le développeur logiciel sera plus à même d’identifier des aires d’améliorations dans son processus individuel de développement. Le but serait d’améliorer sa productivité et améliorer la qualité du produit final.
Niveau projet : Les données récoltées au niveau individuel permettront d’alimenter la base de connaissance du projet pour une meilleure gouvernance agile du projet.
Niveau organisation : Les données sur les différents projets permettront à Pyxis d’avoir une base de données historique pour fin d’estimation.

Trois principaux aspects à considérer dans le modèle de mesure à proposer lesquelles sont inspirés de modèles connus en ingénierie logicielle tels que PSP (Personal software Process) et TSP (Team Software Process) du SEI (Software Engineering Institute). Les mesures en question sont : la taille, le temps et les défauts.
Il est important de savoir que le but n’est pas celui d’implanter PSP ou TSP mais plutôt de s’en inspirer pour identifier les métriques les plus adaptées pour se doter d’une méthode d’ingénierie logicielle agile.
Les mesures et métriques agiles seront définies en collaboration étroite avec les développeurs afin de s’assurer de leurs valeurs ajoutées tant au niveau individuel qu’au niveau projet.
L’introduction des mesures au niveau individuel et au niveau projet se fera progressivement afin de préserver l’agilité de l’équipe.
Comme première étape nous allons prendre le temps de modéliser le processus agile utilisé en pratique par différentes équipes pour différentes catégories de projets. Le but étant d’identifier des besoins éventuels en matière de mesure.
Le parrain de ce projet chez Pyxis est Maurice Bergeron, il travaillera de concert avec l’UQAM.

Merci de partager votre expertise pour enrichir le débat et les résultats attendus !

Agile Tour Grenoble 2009, c parti!

  Après le succès de l'édition 2008, Le Club Agile Rhône Alpes, association pour la promotion des méthodes agiles, organise pour la seconde année consécutive l'étape Grenobloise de l'Agile Tour. Les méthodes agiles visent à améliorer l'efficacité des entreprises et la satisfaction du client final. Ces méthodes proposent de nouvelles approches en termes de pratiques de développement logiciel, de gestion de projet (MOA/MOE), mais aussi sur les aspects organisationnel et de management dans l'entreprise. Sur un plan financier, les méthodes agiles permettent de réduire significativement le coût du changement et assurent au maître d'ouvrage de disposer d'un produit fonctionnel fiable, testé et utilisable en production tout en respectant le budget fixé initialement. L'Agile Tour est un évènement à but non lucratif organisé dans 18 villes à travers le monde, il vise un public de décideurs, d'acheteurs, de managers et d'informaticiens qui souhaitent découvrir ou approfondir les méthodes agiles. Durant la journée vous seront proposées des sessions variées en simultané dans plusieurs espaces (retours d'expériences, exposés techniques, ateliers pratiques …) animées par des orateurs internationaux et locaux de renom:  
Le programme, en cours de finalisation, compte plus d'une vingtaine de contenus réparti sur 6 tracks durant toute une journée.
Un évènement à ne pas manquer ! Bénéficiez d’un tarif spécial en vous inscrivant dès maintenant pour l’évènement de Grenoble. S'inscrire !

Abstracting out static contexts

Any test favoring developer will tell you singletons are the bane of testability. Static contexts make testing difficult. When dealing with legacy code, we are often faced with the problem of testing around such problematic coupling. I’ve had enough opportunity to dable in such code to have developed some strategies in dealing with coupling. In this post I’ll present a strategy I refer to as abstracting out singletons.

For the purpose of discussion I present the following code fragment:

 public class TightlyCoupled { public void quickPurchase(String customerReferenceNumber, int productCode, int quantity) { CustomerCatalog customers = CustomerCatalog.getInstance(); Customer purchaser = customers.find(customerReferenceNumber); if (purchaser == null) throw new UnknownCustomerException(customerReferenceNumber); OrderItem requestedItems = Inventory.getInstance().take(productCode, quantity); Order quickOrder = new Order(purchaser); quickOrder.add(requestedItems); // ... } } 

This code is displays the symptoms of coupling that clearly make testing difficult. Can the inventory and customer catalog be easly programmed to behave in a predictable and testable manner? Your answer will be contextual, but often they cannot. In most enterprise application such singletons will bootstrap the initialization of other singletons as well as database connections. Can these services be easily mocked? Doubtful.

I have seen cases where programmers will allow themselves to override the singleton before the test scenario. This works, but does not help to move away from the current programming model. What we want is to be able to provide an alternate implementation of these services to a constructed instance of the class under test (CUT). The problem with using a dependency injection approach to testing is that most applications developed with singleton spread are rarely blessed with an IoC container to facilitate object construction. Consequently we can rarely allow ourselves to remove the default constructor of the CUT.

So the first thing that I propose is that we consider using a DI approach, and in order to support this we provide two constructors for our CUT: one that allows for the injection of the dependencies, an a default constructor that wires the class with the default dependencies. This quickly leads us to something like this:

public class LessCoupledThroughConstructor { private CustomerCatalog customers; private Inventory inventory; public LessCoupledThroughConstructor( CustomerCatalog customers, Inventory inventory) { this.customers = customers; this.inventory = inventory; } public LessCoupledThroughConstructor() { this(CustomerCatalog.getInstance(), Inventory.getInstance()); } public void quickPurchase( String customerReferenceNumber, int productCode, int quantity) { Customer purchaser = customers.find(customerReferenceNumber); if (purchaser == null) throw new UnknownCustomerException(customerReferenceNumber); OrderItem requestedItems = inventory.take(productCode, quantity); Order quickOrder = new Order(purchaser); quickOrder.add(requestedItems); // ... } } 

So now our CUT can be passed a test friendly set of dependencies with a minimal impact on existing code. What’s more, if the CUT is normally treated as a singleton also, its default constructor can become private, and its instance accessor would not take any dependencies. The test friendly constructor would remain public.

This approach has one drawback. When working on a legacy system that relied heavily on singleton accessors to initialize its services, I quickly discovered that many of these services had developed a kind of magical initialization order. No one knew for certain what that order was, but many bugs in the system were to to it. This minor adjustment I proposed broke the initialization order: the dependency services where initialized in the constructor, and not on first use in the using method. Ka-boom!

No problem. The solution is to introduce a minimal amount of abstraction. I decided to creation some wrapper services. These services delegated operations to the static context on a per-call basis, but where not singletons or static instances themselves. This produces the code bellow:

public class LessCoupledThroughWraping { private CustomerCatalog customers; private Inventory inventory; public LessCoupledThroughWraping( CustomerCatalogService customers, InventoryService inventory) { this.customers = customers; this.inventory = inventory; } public LessCoupledThroughWraping() { this(new GlobalCustomerCatalogService(), new GlobalInventoryService()); } public void quickPurchase( String customerReferenceNumber, int productCode, int quantity) { // as previous example } } 

To give you an idea of what the wraper services look like:

public class GlobalInventoryService implements InventoryService { public OrderItem take(int productCode, int quantity) { return Inventory.getInstance().take(productCode, quantity); } } 

This approached allows the CUT to define a default set of dependencies, but still provides the possibility to inject dependencies.

These approaches are clearly not good examples of applied TDD, but on large systems that have a great deal of code coupling it is often necessary to introduce such test seams. Gradually a large system becomes split into an IoC container friendly design with well tested components.

Other areas where such a strategies work include all static data, static third party APIs, as well as static platform functinality.

An example that I used recently involves the .NET runtime’s “DateTime.Now” which can make testing time dependent behavior unpredictable. My goal was to test that after 10 minutes some condition expired. Obviously I didn’t want a test that ran for ten minutes. I abstract out a date and time service and at test
time I substitute a date time service on which I can set the desired date and time. This makes testing cleaner and more reliable, and in this last case I only needed to redefine the date/time service’s time to jump ahead ten minutes.

What do you think? Have you encountered similar problems? What did you do to work around them?