SlideShare une entreprise Scribd logo
1  sur  39
Changer pour mieux coder
 Ce que vous
 verrez
    Règles pour améliorer son code source

       Démo en live
       Bonus : raccourcis clavier et astuces pour être plus
        productif


Ce que vous ne verrez pas
       Une mise en pratique du TDD (Test Driven Development)
Bienvenue à notre réunion
Développeurs Anonymes (DA)
Application
Magasin (Inn)

     vend


Articles (Items) dont la qualité se dégrade continuellement à l’approche de
la date de péremption
                        SellIn = nombre de jour restant avant la date de péremption
     Article (Item)     Quality = correspond à la valeur de l’objet



A chaque fin de journée, l’application met à jour la qualité de tous les
articles (Inn.updateQuality())
Application
                      SellIn = nombre de jour restant avant la date de péremption
  Article (Item)      Quality = correspond à la valeur de l’objet


Contraintes
  Une fois la date de péremption dépassée, la qualité se dégrade 2 fois plus vite.
  La qualité n’est jamais négative et ne dépasse jamais 50 : 0 ≤ quality ≤ 50.


  “Aged Brie” = la qualité augmente avec le temps qui passe

  “Sulfuras” = article légendaire dont la qualité ne décroit jamais et qui n’a pas de
  date de péremption.

  “Backstage passes” = la qualité augmente avec le temps de la manière suivante :
      6 ≤ sellIn ≤ 10 → la qualité augmente par 2
      0 ≤ sellIn ≤ 5 → la qualité augmente par 3
      sellIn < 0 → la qualité = 0
Entrainons-nous !


        Emmanuel Chenu
9 règles pour votre gymnastique objet
  1. Use one level of indentation per method
  2. Don't use the else keyword
  3. Wrap all primitives and strings
  4. Use only one dot per line
  5. Don't abbreviate
  6. Keep all entities small
  7. Don't use any classes with more than two instance variables
  8. Use first class collections
  9. Don't use any getters, setters or properties

    Object Calisthenics by Jeff Bay tiré du livre ThoughtWorks Anthology
1. Use one level of indentation per method
2. Don’t use the else keyword

     Early Return
     Utiliser une map
     Polymorphisme
          – Stratégie
          – Null Object
     Empty lists
     …
3. Wrap all primitives and strings
public class Discounter {


    private Integer discount;

    […]
}



                                public class Money {
public class Discounter {
                                    private Integer amountInCents;

                                    public Money(Integer amountInCents) {
    private Money discount;
                                      this.amountInCents = amountInCents;
                                    }
    […]
}
                                    […]
                                }
4. Use only one dot per line

     Loi de Demeter
      « Ne parlez pas aux inconnus »
5. Don’t abbreviate

     Répétition signifie souvent un concept commun à faire émerger
6. Keep all entities small

      Pas de classe > 50 lignes
      Pas de paquet > 10 classes


      « Single Responsibility Principle »
7. Don't use any classes with more than two
instance variables
      Cohésion
      Emergence de model à grain fin
      Ex OrangeForge : User & Project => Permissions?
8. Use first class collections

      Le pendant Wrap all primitives
      Centralise traitements sur la collection
9. Don't use any getters, setters or
properties

 q.setQuality(q.getQuality() - 1);                   q.decrease();



 q.quality = 0;                                     q.dropToZero();




                               « Tell don’t ask »
Bilan
 Règles   2. Don't use the else keyword
          3. Wrap all primitives and strings
          9. Don't use any getters, setters or properties


          code plus lisible, maintenable et évolutif

          cela a été une aide




 Nécessité des tests pour le refactoring.
Acteurs
Le Parrain                             Le Filleul



             Johan MARTINSSON                      Rémy SANLAVILLE
Indépendant                                 Développeur
martinsson.johan@gmail.com                  remy.sanlaville@orange.com
@johan_alps                                 @sanlaville
Discussions
Update Quality for Backstage
Update Backstage passes

                          [sellIn ≥ 11]
   Cas 1                                  qualité += 1
Update Quality for Backstage
Update Backstage passes

                          [sellIn ≥ 11]
   Cas 1                                  qualité += 1
Update Quality for Backstage
Update Backstage passes

                            [sellIn ≥ 11]
   Cas 1                                      qualité += 1


                          [10 ≥ sellIn ≥ 6]
   Cas 2                                      qualité += 2


                          [5 ≥ sellIn ≥ 0]
   Cas 3                                      qualité += 3


                            [0 > sellIn]
   Cas 4                                      qualité = 0
Solution 1 : if
                                                         demo-live
Update Backstage passes


                                   quality.increase();


         if   [getSellIn() < 11]
                                   quality.increase();
Solution 1 : if
                                                         demo-live
Update Backstage passes


                                   quality.increase();


         if   [getSellIn() < 11]
                                   quality.increase();
Solution 1 : if
                                                         demo-live
Update Backstage passes


                                   quality.increase();


         if   [getSellIn() < 11]
                                   quality.increase();
Solution 1 : if
                                                                 demo-live
Update Backstage passes


                                   quality.increase();


         if   [getSellIn() < 11]
                                   quality.increase();


         if   [getSellIn() < 6]
                                   quality.increase();


                                   setSellIn(getSellIn() - 1);

         if   [getSellIn() < 0]
                                    quality.dropToZero();
Solution 2 : if - else
                                                  Tag : backstageWithElseIf
Update Backstage passes

 if   [daysBefore > 10]
                          quality.increaseBy(1)
Solution 2 : if - else
                                                  Tag : backstageWithElseIf
Update Backstage passes

 if   [daysBefore > 10]
                          quality.increaseBy(1)
Solution 2 : if - else
                                                           Tag : backstageWithElseIf
Update Backstage passes

 if     [daysBefore > 10]
                                   quality.increaseBy(1)


      else if   [daysBefore > 5]
                                        quality.increaseBy(2)


                else if   [daysBefore > 0]
                                                 quality.increaseBy(3)


                            else
                                                 quality.resetToZero()
Solution 3 : Range Map
                                                                Tag : rangeMap
Update Backstage passes
         Initialisation de la Map
                   strategies = new TreeMap<Integer, IncreaseStrategy>() {{
                          put(Integer.MIN_VALUE, new ResetToZero());
                          put(0, new IncreaseBy(3));
                          put(5, new IncreaseBy(2));
                          put(10, new IncreaseBy(1));
                   }};
Solution 3 : Range Map
                                                                Tag : rangeMap
Update Backstage passes
         Initialisation de la Map
                   strategies = new TreeMap<Integer, IncreaseStrategy>() {{
                          put(Integer.MIN_VALUE, new ResetToZero());
                          put(0, new IncreaseBy(3));
                          put(5, new IncreaseBy(2));
                          put(10, new IncreaseBy(1));
                   }};
Solution 3 : Range Map
                                                               Tag : rangeMap
Update Backstage passes
         Initialisation de la Map
                   strategies = new TreeMap<Integer, IncreaseStrategy>() {{
                          put(Integer.MIN_VALUE, new ResetToZero());
                          put(0, new IncreaseBy(3));
                          put(5, new IncreaseBy(2));
                          put(10, new IncreaseBy(1));
                   }};

  Récupération de la stratégie
       strategies.lowerEntry(daysBefore).getValue();

  Appliquer la stratégie
         strategy().applyTo(quality);
Solution 4 : DSL
                                                   Tag : backstageUpdateDSL
Update Backstage passes


         quality.doIncreaseBy(1).when(daysBefore, greaterThan(10));
Solution 4 : DSL
                                                   Tag : backstageUpdateDSL
Update Backstage passes


         quality.doIncreaseBy(1).when(daysBefore, greaterThan(10));
Solution 4 : DSL
                                                   Tag : backstageUpdateDSL
Update Backstage passes


         quality.doIncreaseBy(1).when(daysBefore, greaterThan(10));
         quality.doIncreaseBy(2).when(daysBefore, between(5, 10));
         quality.doIncreaseBy(3).when(daysBefore, between(0, 5));
         quality.doResetToZero().when(daysBefore, lessThanOrEqualTo(0));
Conclusion

 Les règles peuvent-être vues comme une chance
 pour sortir du cadre et réfléchir autrement plutôt
 que comme des contraintes.


 Pour s’améliorer, il faut savoir prendre du temps
 pour s’exercer.
En savoir plus

     Thoughtworks Anthology by PragProg
      http://pragprog.com/book/twa/thoughtworks-anthology

     Object Calisthenics
      http://www.bennadel.com/resources/uploads/2012/ObjectCalisthenics.pdf

     How object oriented are you feeling today?
      Krzysztof Jelski - Software Craftsmanship 2011 Conference
      http://fr.slideshare.net/KrzysztofJelski/how-object-oriented-are-you-feeling-today
Liens
Plugins Eclipse                                Raccourcis clavier Eclipse
    Infinitest (http://infinitest.github.com)      Ctrl + 1
    MoreUnit (http://moreunit.sourceforge.net/)    Alt + Shift + T
    EclEmma (http://www.eclemma.org/)



Clipboard Manager
    Ditto (http://ditto-cp.sourceforge.net/)


Code sous GitHub
    https://github.com/sanlaville/AgileGrenoble2012.git
    https://github.com/martinsson/AgileGrenoble2012.git
N’oubliez pas de remplir les feedbacks !

Contenu connexe

Plus de martinsson

Testing strategies visualized
Testing strategies visualizedTesting strategies visualized
Testing strategies visualizedmartinsson
 
Split my monolith! Workshop
Split my monolith! Workshop Split my monolith! Workshop
Split my monolith! Workshop martinsson
 
No Agility without Continuous Delivery
No Agility without Continuous DeliveryNo Agility without Continuous Delivery
No Agility without Continuous Deliverymartinsson
 
No agility without continuous delivery frugagile
No agility without continuous delivery   frugagileNo agility without continuous delivery   frugagile
No agility without continuous delivery frugagilemartinsson
 
De legacy au tdd agilegrenoble
De legacy au tdd   agilegrenobleDe legacy au tdd   agilegrenoble
De legacy au tdd agilegrenoblemartinsson
 
De legacy au tdd - Agile pays basque
De legacy au tdd  - Agile pays basqueDe legacy au tdd  - Agile pays basque
De legacy au tdd - Agile pays basquemartinsson
 
Usable software design ncraft
Usable software design ncraftUsable software design ncraft
Usable software design ncraftmartinsson
 
Usable software design - code utilisable
Usable software design - code utilisableUsable software design - code utilisable
Usable software design - code utilisablemartinsson
 
Une architecture agile et testable
Une architecture agile et testableUne architecture agile et testable
Une architecture agile et testablemartinsson
 
Pyramide des tests
Pyramide des testsPyramide des tests
Pyramide des testsmartinsson
 

Plus de martinsson (12)

Testing strategies visualized
Testing strategies visualizedTesting strategies visualized
Testing strategies visualized
 
Split my monolith! Workshop
Split my monolith! Workshop Split my monolith! Workshop
Split my monolith! Workshop
 
No Agility without Continuous Delivery
No Agility without Continuous DeliveryNo Agility without Continuous Delivery
No Agility without Continuous Delivery
 
No agility without continuous delivery frugagile
No agility without continuous delivery   frugagileNo agility without continuous delivery   frugagile
No agility without continuous delivery frugagile
 
De legacy au tdd agilegrenoble
De legacy au tdd   agilegrenobleDe legacy au tdd   agilegrenoble
De legacy au tdd agilegrenoble
 
De legacy au tdd - Agile pays basque
De legacy au tdd  - Agile pays basqueDe legacy au tdd  - Agile pays basque
De legacy au tdd - Agile pays basque
 
Usable software design ncraft
Usable software design ncraftUsable software design ncraft
Usable software design ncraft
 
Usable software design - code utilisable
Usable software design - code utilisableUsable software design - code utilisable
Usable software design - code utilisable
 
Une architecture agile et testable
Une architecture agile et testableUne architecture agile et testable
Une architecture agile et testable
 
Pyramide des tests
Pyramide des testsPyramide des tests
Pyramide des tests
 
Mikado
MikadoMikado
Mikado
 
Mikado
MikadoMikado
Mikado
 

Changer Pour Mieux Coder

  • 1. Changer pour mieux coder Ce que vous verrez  Règles pour améliorer son code source  Démo en live  Bonus : raccourcis clavier et astuces pour être plus productif Ce que vous ne verrez pas  Une mise en pratique du TDD (Test Driven Development)
  • 2. Bienvenue à notre réunion Développeurs Anonymes (DA)
  • 3. Application Magasin (Inn) vend Articles (Items) dont la qualité se dégrade continuellement à l’approche de la date de péremption SellIn = nombre de jour restant avant la date de péremption Article (Item) Quality = correspond à la valeur de l’objet A chaque fin de journée, l’application met à jour la qualité de tous les articles (Inn.updateQuality())
  • 4. Application SellIn = nombre de jour restant avant la date de péremption Article (Item) Quality = correspond à la valeur de l’objet Contraintes Une fois la date de péremption dépassée, la qualité se dégrade 2 fois plus vite. La qualité n’est jamais négative et ne dépasse jamais 50 : 0 ≤ quality ≤ 50. “Aged Brie” = la qualité augmente avec le temps qui passe “Sulfuras” = article légendaire dont la qualité ne décroit jamais et qui n’a pas de date de péremption. “Backstage passes” = la qualité augmente avec le temps de la manière suivante : 6 ≤ sellIn ≤ 10 → la qualité augmente par 2 0 ≤ sellIn ≤ 5 → la qualité augmente par 3 sellIn < 0 → la qualité = 0
  • 5. Entrainons-nous ! Emmanuel Chenu
  • 6. 9 règles pour votre gymnastique objet 1. Use one level of indentation per method 2. Don't use the else keyword 3. Wrap all primitives and strings 4. Use only one dot per line 5. Don't abbreviate 6. Keep all entities small 7. Don't use any classes with more than two instance variables 8. Use first class collections 9. Don't use any getters, setters or properties Object Calisthenics by Jeff Bay tiré du livre ThoughtWorks Anthology
  • 7. 1. Use one level of indentation per method
  • 8. 2. Don’t use the else keyword  Early Return  Utiliser une map  Polymorphisme – Stratégie – Null Object  Empty lists  …
  • 9. 3. Wrap all primitives and strings public class Discounter { private Integer discount; […] } public class Money { public class Discounter { private Integer amountInCents; public Money(Integer amountInCents) { private Money discount; this.amountInCents = amountInCents; } […] } […] }
  • 10. 4. Use only one dot per line  Loi de Demeter « Ne parlez pas aux inconnus »
  • 11. 5. Don’t abbreviate  Répétition signifie souvent un concept commun à faire émerger
  • 12. 6. Keep all entities small  Pas de classe > 50 lignes  Pas de paquet > 10 classes  « Single Responsibility Principle »
  • 13. 7. Don't use any classes with more than two instance variables  Cohésion  Emergence de model à grain fin  Ex OrangeForge : User & Project => Permissions?
  • 14. 8. Use first class collections  Le pendant Wrap all primitives  Centralise traitements sur la collection
  • 15. 9. Don't use any getters, setters or properties q.setQuality(q.getQuality() - 1); q.decrease(); q.quality = 0; q.dropToZero(); « Tell don’t ask »
  • 16. Bilan Règles 2. Don't use the else keyword 3. Wrap all primitives and strings 9. Don't use any getters, setters or properties code plus lisible, maintenable et évolutif cela a été une aide Nécessité des tests pour le refactoring.
  • 17. Acteurs Le Parrain Le Filleul Johan MARTINSSON Rémy SANLAVILLE Indépendant Développeur martinsson.johan@gmail.com remy.sanlaville@orange.com @johan_alps @sanlaville
  • 19. Update Quality for Backstage Update Backstage passes [sellIn ≥ 11] Cas 1 qualité += 1
  • 20. Update Quality for Backstage Update Backstage passes [sellIn ≥ 11] Cas 1 qualité += 1
  • 21. Update Quality for Backstage Update Backstage passes [sellIn ≥ 11] Cas 1 qualité += 1 [10 ≥ sellIn ≥ 6] Cas 2 qualité += 2 [5 ≥ sellIn ≥ 0] Cas 3 qualité += 3 [0 > sellIn] Cas 4 qualité = 0
  • 22. Solution 1 : if demo-live Update Backstage passes quality.increase(); if [getSellIn() < 11] quality.increase();
  • 23. Solution 1 : if demo-live Update Backstage passes quality.increase(); if [getSellIn() < 11] quality.increase();
  • 24. Solution 1 : if demo-live Update Backstage passes quality.increase(); if [getSellIn() < 11] quality.increase();
  • 25. Solution 1 : if demo-live Update Backstage passes quality.increase(); if [getSellIn() < 11] quality.increase(); if [getSellIn() < 6] quality.increase(); setSellIn(getSellIn() - 1); if [getSellIn() < 0] quality.dropToZero();
  • 26. Solution 2 : if - else Tag : backstageWithElseIf Update Backstage passes if [daysBefore > 10] quality.increaseBy(1)
  • 27. Solution 2 : if - else Tag : backstageWithElseIf Update Backstage passes if [daysBefore > 10] quality.increaseBy(1)
  • 28. Solution 2 : if - else Tag : backstageWithElseIf Update Backstage passes if [daysBefore > 10] quality.increaseBy(1) else if [daysBefore > 5] quality.increaseBy(2) else if [daysBefore > 0] quality.increaseBy(3) else quality.resetToZero()
  • 29. Solution 3 : Range Map Tag : rangeMap Update Backstage passes Initialisation de la Map strategies = new TreeMap<Integer, IncreaseStrategy>() {{ put(Integer.MIN_VALUE, new ResetToZero()); put(0, new IncreaseBy(3)); put(5, new IncreaseBy(2)); put(10, new IncreaseBy(1)); }};
  • 30. Solution 3 : Range Map Tag : rangeMap Update Backstage passes Initialisation de la Map strategies = new TreeMap<Integer, IncreaseStrategy>() {{ put(Integer.MIN_VALUE, new ResetToZero()); put(0, new IncreaseBy(3)); put(5, new IncreaseBy(2)); put(10, new IncreaseBy(1)); }};
  • 31. Solution 3 : Range Map Tag : rangeMap Update Backstage passes Initialisation de la Map strategies = new TreeMap<Integer, IncreaseStrategy>() {{ put(Integer.MIN_VALUE, new ResetToZero()); put(0, new IncreaseBy(3)); put(5, new IncreaseBy(2)); put(10, new IncreaseBy(1)); }}; Récupération de la stratégie strategies.lowerEntry(daysBefore).getValue(); Appliquer la stratégie strategy().applyTo(quality);
  • 32. Solution 4 : DSL Tag : backstageUpdateDSL Update Backstage passes quality.doIncreaseBy(1).when(daysBefore, greaterThan(10));
  • 33. Solution 4 : DSL Tag : backstageUpdateDSL Update Backstage passes quality.doIncreaseBy(1).when(daysBefore, greaterThan(10));
  • 34. Solution 4 : DSL Tag : backstageUpdateDSL Update Backstage passes quality.doIncreaseBy(1).when(daysBefore, greaterThan(10)); quality.doIncreaseBy(2).when(daysBefore, between(5, 10)); quality.doIncreaseBy(3).when(daysBefore, between(0, 5)); quality.doResetToZero().when(daysBefore, lessThanOrEqualTo(0));
  • 35. Conclusion Les règles peuvent-être vues comme une chance pour sortir du cadre et réfléchir autrement plutôt que comme des contraintes. Pour s’améliorer, il faut savoir prendre du temps pour s’exercer.
  • 36. En savoir plus  Thoughtworks Anthology by PragProg http://pragprog.com/book/twa/thoughtworks-anthology  Object Calisthenics http://www.bennadel.com/resources/uploads/2012/ObjectCalisthenics.pdf  How object oriented are you feeling today? Krzysztof Jelski - Software Craftsmanship 2011 Conference http://fr.slideshare.net/KrzysztofJelski/how-object-oriented-are-you-feeling-today
  • 37. Liens Plugins Eclipse Raccourcis clavier Eclipse Infinitest (http://infinitest.github.com) Ctrl + 1 MoreUnit (http://moreunit.sourceforge.net/) Alt + Shift + T EclEmma (http://www.eclemma.org/) Clipboard Manager Ditto (http://ditto-cp.sourceforge.net/) Code sous GitHub https://github.com/sanlaville/AgileGrenoble2012.git https://github.com/martinsson/AgileGrenoble2012.git
  • 38.
  • 39. N’oubliez pas de remplir les feedbacks !

Notes de l'éditeur

  1. presentation title