Archive

Articles de Pierre-Yves RICAU

Son site web : http://www.piwai.info

Mieux le connaître


Vous pouvez me retrouver sur Twitter, suivre mes projets sur ohloh, et découvrir mon parcours sur LinkedIn.

La SCJP, c’est pas de la menthe à l’eau

Les JDuchess françaises ont récemment décidé d’organiser un groupe de travail pour les personnes souhaitant passer la certification SCJP.  Après avoir donné mon retour d’expérience sur la mailing list dédiée, je me suis dit qu’il serait intéressant d’en faire un article.

Lire la suite…

Refactoring par la pratique

Dans cet article, nous allons procéder à un refactoring sur un exemple concret, afin de mettre en exergue quelques bonnes pratiques.

Défi : comprendre du code inélégant*

*Edit : j’avais initialement écrit “imb*table”, mais il paraît que ça ne fait pas très sérieux :-P

Êtes-vous capable de comprendre ce que fait la méthode computeConvexHull() en moins de 3 minutes ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public List<GeoPoint> computeConvexHull(Set<GeoPoint> points) {

    // Path list
    ArrayList<GeoPoint> path = new ArrayList<GeoPoint>();

    // Pick the min longitude point as first
    GeoPoint first = null;
    for (GeoPoint point : points) {
        if (first == null || point.getLongitude() < first.getLongitude()) {
            first = point;
        }
    }

    if (first != null) {
        path.add(first);
    } else {
        throw new IllegalArgumentException("Can't retrieve the western point");
    }

    boolean right = true;
    boolean loop = true;

    while (loop) {

        GeoPoint current = path.get(path.size() - 1);

        GeoPoint next = null;
        double nextLatitudeDiff = 0;
        double nextLongitudeDiff = 0;
        boolean recordNext = false;
        for (GeoPoint point : points) {
            if (!point.equals(current)) {
                double latitudeDiff = point.getLatitude() - current.getLatitude();
                double longitudeDiff = point.getLongitude() - current.getLongitude();
                if (longitudeDiff == 0 || longitudeDiff > 0 == right) {
                    if (next == null) {
                        recordNext = true;
                    } else {
                        // Compare the 'a' in the linear equation Y = a.X
                        // that correspond to the line slope.
                        boolean negativeSlope = latitudeDiff * nextLongitudeDiff - nextLatitudeDiff * longitudeDiff < 0;

                        if (negativeSlope) {
                            recordNext = true;
                        }
                    }

                    if (recordNext) {
                        recordNext = false;
                        next = point;
                        nextLatitudeDiff = latitudeDiff;
                        nextLongitudeDiff = longitudeDiff;
                    }
                }
            }
        }

        if (next != null) {

            // Check abnormal case
            if (path.size() > points.size() + 1) {
                throw new RuntimeException("Convex hull computation failed");
            }

            path.add(next);

            /*
             * If we are not back to the first point, let's continue finding
             * the path.
             *
             * Otherwise, do nothing => going back from the stack, this is
             * actually the end point of the recursive algorithm.
             */


            if (path.get(0) == next) {
                loop = false;
            }

        } else {
            // We have reached the point on the right, let's go back!
            right = !right;
        }
    }

    return path;
}

Alors ? Checkstyle lui donne une complexité cyclomatique de 16. Plutôt difficile d’y voir clair. Moi en tout cas, je n’en suis pas capable.
Et pourtant, j’en suis l’auteur :-) . Critique de code bien ordonnée commence par soi-même ! Lire la suite…

Dé-switcher n’est pas jouer

Amis utilisateurs de Checkstyle, avez-vous remarqué que les switch sont des sources inépuisables de complexité cyclomatique ? Sans parler de leur équivalent pour les objets, les if () {} else if (){} else if (){} else if (){} à répétition.

Parmi les reproches récurrents faits aux switch, il y a le fait qu’ils ne respectent pas le principe Ouvert/Fermé. A chaque ajout de nouvelles valeurs, il faut modifier tous les switch qui les manipulent.

Lire la suite…

Compte-rendu du Paris JUG : soirée Build, Share & Deploy

Aujourd’hui, nous tentons une expérience : écrire un article à plusieurs. Mais plutôt que de s’abriter derrière un “nous” anonyme et sécurisant, nous (sic !) avons décidé de continuer à employer la première personne, en précisant qui est le locuteur lorsque c’était nécessaire. A vous de nous dire si vous appréciez le format ;-) !

Une fois n’est pas coutume, ce deuxième mardi du mois a été l’occasion pour les Javaïstes parisiens d’assister au Paris JUG, consacré cette fois aux processus de build, share et deployment. Pas de chance, la salle était déjà bien pleine quand je (Bastien) suis arrivé… vite, une chaise tout devant !

De mon côté (Pierre-Yves), ayant posé ma tente devant la salle la veille au soir, j’ai eu accès aux premiers rangs. Allez, je vous livre un petit secret : pour avoir un placement correct au Paris Jug, il faut arriver à 19h ;-) (ou être une JDuchess :-P ). Je (Pierre-Yves) vais donc vous parler des trois premières présentations, et je (Bastien) continuerai avec les deux dernières.

Lire la suite…

CAS et Grails, sans sarCASmes !

Grails.orgCAS

Propos liminaire

Cet article traite de la cassification d’une application Grails. Ce néologisme pas très catholique, plus souvent employé dans la langue Shakespearienne, est synonyme d’intégration d’une application avec le système d’authentification centralisée Open Source le plus stylé au monde, j’ai nommé : CAS.

Lire la suite…