Ok

En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies. Ces derniers assurent le bon fonctionnement de nos services. En savoir plus.

25 mars 2010

Retour d'expérience sur les codings dojos

Le 24 mars 2010, j'ai présenté le retour d'expérience de l'utilisation des coding dojos à Hydro-Québec au groupe agile de Montréal. Une copie de la présentation se trouve ici.

Le coding dojo est une activité de formation novatrice et très efficace. Il s'agit d'un espace de co-apprentissage, où les participants apprennent les uns des autres en codant des solutions à des défis de programmation plus ou moins complexe. L'objectif n'est pas de résoudre le problème mais plutôt de se concentrer sur la démarche pour le résoudre, donc sur la conception.

Typiquement les dojos utilisent le Test Driven Developpement comme technique centrale. Il existe deux formules pour le déroulement du dojo: le kata, où un développeur solutionne un défi en partant de la page blanche et en expliquant sa démarche, étape par étape, test par test. et le randori où on fonctionne par binôme (pair programming) en faisant une rotation du binôme au 5 minutes. Dans les deux cas, les participants peuvent intervenir s'ils ne comprennent pas la démarche de solution, et dans le randori, le binône peut demander l'aide des participants s'il bloque sur un point. Généralement on débute le dojos par une présentation du défis et on esquisse la solution par un petit modèle objet. On termine le dojo par une courte rétrospective.

 L'expérience à Hydro-Québec a été positive. Un bilan à été réalisé après une série de six dojos (2 en kata et 4 en randori). Le taux de satisfaction des participants (un dizaine) était de 8 sur 10 et tous on trouvé l'approche intéressante pour améliorer leurs compétences.

Pour les moments les dojos sont suspendus, mais ils devraient reprendre sous peu avec un meilleur support, qui intègre les leçons apprises lors des six dojos. La présentation offre plus de détails.

 

26 février 2010

Créer des données au démarrage dans Grails

Créer des données dans le BootStrap

Le BootStrap est une classe située dans le dossier /grails-app/conf du projet. Elle peut servir, entre-autre, à ajouter des données lors du démarrage. On peut commencer par détecter dans quel type d'environnement on se trouve en utilisant un «break»:

def init = { servletContext ->

switch (GrailsUtil.environment)

{

case "development":

println "**** BootStrap Développement en cous ..."

configureForDevelopment()

break

case "test":

println "**** BootStrap Test en cous ..."

configureForTest()

break

case "production":

println "**** BootStrap Production en cous ..."

configureForProduction()

break

}

println "**** Fin BootStrap"

}

On peut ensuite tester s'il y a des données déjà existantes et en ajouter si ce n'est pas le cas:

if (Technologie.count() == 0) {

println " - Création Technologie"

def tech = new Technologie(nom:"Non Connue")

tech.validate()

println tech

tech.errors.allErrors.each {

println it

}

tech.save(flush:true)

Qui devrait donner quelque chose du genre:

Inventaire applicatif du DMDI - CK

Field error in object 'ca.qc.hydro.ck.Application' on field 'contacts.role': rejected value [null]; …

Field error in object 'ca.qc.hydro.ck.Application' on field 'marche': rejected value [null]; …

Field error in object 'ca.qc.hydro.ck.Application' on field 'planificateur': rejected value [null]; …

Field error in object 'ca.qc.hydro.ck.Application' on field 'ressources.role': rejected value [null]; …

Field error in object 'ca.qc.hydro.ck.Application' on field 'uniteApplications.role': rejected value [null]; …

 

La méthode «validate» sert à peupler le champ «errors» de «tech» et le «flush:true» sert à indiquer qu'il faut persister ce qui vient d'être sauvegardé immédiatement. On peut aussi ajouter/retirer des éléments relationnels (de type: a hasMany b) en utilisant la méthode addTo/removeFrom :

applicationInstance.addToUniteApplications(uniteStructurelle:UniteStructurelle.findByDescriptionIlike("%Équipe sécurité%"),role:RoleUniteStructurelle.findByNom("Client"))

Diagramme de classe UML dans Grails

 

Créer un diagramme de classe UML du domaine

Le plugin CreateDomainUML permet de documenter les classes du domaine. Voici une des représentation possible.

uml.jpg

 

 

06 février 2010

Mise en relief des champs obligatoires

 

Mise en relief des champs obligatoires

Étant donnée que nos objets de domaine indique par les contraintes si les propriétés sont obligatoires ou facultatives, on voudrait le refléter dans l'écran de saisie. Dans nos normes on affiche ces champs avec une étoile rouge.

La façon la plus simple est de se construire un tablib qui vérifie l'état de la contrainte isNullable et d'outputter une classe correspondante, qui se trouve dans le CSS.

Ainsi, si on modifie les contraintes dans la définition de la classe, la vue le reflète automatiquement.

Le taglib:

 

class UtilJDTagLib {

def utilHTML = { attrs, body ->

out << "${attrs['thru']}"

}

def utilOblig = { attrs, body ->

if (attrs['bean'].constraints.get(attrs['field']).isNullable())

{ out << 'facultatif'}

else {out << 'obligatoire' }

}

}

Dans la vue, il s'agit de rajouter notre taglib dans la classe de l'élément, par exemple dans la view Create.gsp du projet, ici le label.

<g:form action="save" method="post" >

<div class="dialog">

<table>

<tbody>

<tr class="prop">

<td valign="top" class="name">

<label for="numero" class="<g:utilOblig bean="${projetInstance}" field="numero" />"><g:message code="projet.numero" default="Numero" />:</label>

</td>

<td valign="top" class="value ${hasErrors(bean: projetInstance, field: 'numero', 'errors')} ">

<g:textField name="numero" value="${fieldValue(bean: projetInstance, field: 'numero')}" />

</td>

</tr>

<tr class="prop">

<td valign="top" class="name">

<label for="nom" class="<g:utilOblig bean="${projetInstance}" field="nom" />"><g:message code="projet.nom" default="Nom" />:</label>

</td>

<td valign="top" class="value ${hasErrors(bean: projetInstance, field:'nom', 'errors')} ">

<g:textField name="nom" maxlength="80" value="${fieldValue(bean: projetInstance, 'nom')}" />

</td>

</tr>

Ce qui donne à l'écran:

 

oblig01.jpg