The Good the Bad and the Ugly of Dealing with Smelly Code (ITAKE Unconference)

4,576 views

Published on

We all have a burning desire to write clean code. Every morning we wake up, look in the mirror, and promise ourselves that today we will follow the principles and best practices learned from Uncle Bob and his disciples. But we live in a cruel environment, surrounded by millions of smelly lines of code, reflections of a stinky design… and these constantly challenge our pure-hearted desire for writing clean code.
In such an environment, the stubbornness to practice daily the writing of clean code is vital.
But is it enough? Can we avoid getting lost in a sea of smelly code and design?
In this talk I will try to persuade you that, in dealing with large-scale systems, craftsmanship must be supported by proper techniques and tools that can help us to quickly understand, assess and improve the sea of smelly design that surrounds us.
I will present a pragmatic approach on how design anti-patterns (e.g. God Class, Feature Envy, Refused Bequest, Shotgun Surgery) can be automatically detected using a set of metrics-based detection rules, by analyzing the history of the system, and by using intriguing software visualizations.
The presentation will also include a live demo of tools that can automate the entire approach to a high-extent. These tools are so robust that they can deal with systems of several million lines of code; but they are also friendly enough to provide you with customized hints that help you deal with each and every case of an “unclean” code.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
4,576
On SlideShare
0
From Embeds
0
Number of Embeds
3,170
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

The Good the Bad and the Ugly of Dealing with Smelly Code (ITAKE Unconference)

  1. 1. The Good the Bad and the Ugly ofDealing with Smelly CodeDr. Radu Marinescuradum@intooitus.comIT.A.K.E - May 30, 2013
  2. 2. I, me and myself...
  3. 3. my two hats...
  4. 4. the academic one
  5. 5. Full Professor. PhD Advisorsoftware engineeringsince 2013
  6. 6. software maintenance. quality assuranceCo-founder. Headsince 2003
  7. 7. ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005
  8. 8. ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005 ECOOP 1998 WCRE 2005WCRE 2004 SYNASC 2005500+citationsin mainstreampublications
  9. 9. Michele LanzaRadu MarinescuObject-OrientedMetricsin PracticeUsing Software Metrics toCharacterize, Evaluate, and Improvethe Design of Object-Oriented SystemsForeword by Stéphane DucasseLanza·MarinescuObject-OrientedMetricsinPracticetant Professor at the University of Lugano, Switzer-rests lie in software (re)engineering and software evo-n software visualization and metrics. He is the creatorailable language-independent software visualizatione Ernst Denert Software Engineering Award in 2003.istant Professor at the Politehnica University ofearch focus is on object-oriented design, reenginee-He is the author of a suite of novel object-orientedor of iPlasma, an integrated and freely available tool-. Several of his published research ideas have alreadyown “Borland Together Control Center” CASE tool.ented Metrics invery engineering discipline. However, due to its lackmplexity, software engineering is not considered ay. Moreover, defining, understanding and applyings like an overly complex activity, recommended onlygeneral, if a software system is delivering thefew people – if any – care about measuring the qua-Consequently, software metrics are still regardedst software developers.stify the design metrics used to assess the size,bject-oriented software systems. Based on a novelally accepted semantics for metrics and by statisticalustrial projects, they deduce a suite of metrics-basedesign of object-oriented software systems. Theyfy design disharmonies in code, and how to devisecally sound results and practically tested procedu-es this book an ideal companion for professionalpers and quality engineers. The pattern-oriented des-ers easy access to detecting shortcomings andoblems.ect-oriented*many reengineering strategiesfor poorly structured code*brief introduction to softwarevisualization‘’This well-written book is an impor-tant piece of work that takes theseemingly forgotten art of object-oriented metrics to the next level interms of relevance and usefulness.’Richard C. Gronback,Chief Scientist, Borland SoftwareCorporation1 31
  10. 10. Michele LanzaRadu MarinescuObject-OrientedMetricsin PracticeUsing Software Metrics toCharacterize, Evaluate, and Improvethe Design of Object-Oriented SystemsForeword by Stéphane DucasseLanza·MarinescuObject-OrientedMetricsinPracticetant Professor at the University of Lugano, Switzer-rests lie in software (re)engineering and software evo-n software visualization and metrics. He is the creatorailable language-independent software visualizatione Ernst Denert Software Engineering Award in 2003.istant Professor at the Politehnica University ofearch focus is on object-oriented design, reenginee-He is the author of a suite of novel object-orientedor of iPlasma, an integrated and freely available tool-. Several of his published research ideas have alreadyown “Borland Together Control Center” CASE tool.ented Metrics invery engineering discipline. However, due to its lackmplexity, software engineering is not considered ay. Moreover, defining, understanding and applyings like an overly complex activity, recommended onlygeneral, if a software system is delivering thefew people – if any – care about measuring the qua-Consequently, software metrics are still regardedst software developers.stify the design metrics used to assess the size,bject-oriented software systems. Based on a novelally accepted semantics for metrics and by statisticalustrial projects, they deduce a suite of metrics-basedesign of object-oriented software systems. Theyfy design disharmonies in code, and how to devisecally sound results and practically tested procedu-es this book an ideal companion for professionalpers and quality engineers. The pattern-oriented des-ers easy access to detecting shortcomings andoblems.ect-oriented*many reengineering strategiesfor poorly structured code*brief introduction to softwarevisualization‘’This well-written book is an impor-tant piece of work that takes theseemingly forgotten art of object-oriented metrics to the next level interms of relevance and usefulness.’Richard C. Gronback,Chief Scientist, Borland SoftwareCorporation1 311000+reprinted2010
  11. 11. Innovation Award 20062006Continuous detection of design problems
  12. 12. “...have done the most to improve programmer productivity ...”IBM2009
  13. 13. “...have done the most to improve programmer productivity ...”IBMjury includedGrady Booch, Erich Gamma,Fred Brooks, Frances Allen2009
  14. 14. WorkingConferenceonReverse EngineeringInternationalConferenceonProgram ComprehensionConferenceonSoftwareMaintenance & Re-Engineering
  15. 15. International Conference on Software Maintenance2010General Chair
  16. 16. T.J. Watson ResearchInvited Talks
  17. 17. Consultancy & Trainings
  18. 18. my entrepreneurial hat
  19. 19. Co-Founderwww.intooitus.com
  20. 20. Dr. Radu MarinescuDr. Adrian Trifu Dr. Mircea Trifu George Ganea Ioana Verebi
  21. 21. Dr. Radu MarinescuDr. Adrian Trifu Dr. Mircea Trifu George Ganea Ioana Verebi...uniquely innovative tools, and project-specific consultancyto support complex quality assessment tasksin large-scale software systems
  22. 22. inFusioncontrol the architecture and design quality of your system!http://www.intooitus.com/products/infusion
  23. 23. inFusion
  24. 24. inFusion1+ Billion LOC total
  25. 25. inFusion1+ Billion LOC total10.000+ users
  26. 26. inFusion1+ Billion LOC total10.000+ users
  27. 27. your daily companion for code and design qualityhttp://www.intooitus.com/products/incodeinCode
  28. 28. your daily companion for code and design qualityhttp://www.intooitus.com/products/incodeinCodeNew versionlaunched yesterday!
  29. 29. Setting the stage ...
  30. 30. 1946
  31. 31. 1951
  32. 32. 1951
  33. 33. 1951
  34. 34. 1951 2013
  35. 35. 1951 2013
  36. 36. ?1951 2013
  37. 37. Software is complex
  38. 38. Software is complex.The Standish Group, 200453% Challenged18% Failed29% Succeeded
  39. 39. }{}{}{}{}{How complexis your project?
  40. 40. 1’000’000 lines of code
  41. 41. 1’000’000 lines of code* 3 = 3’000’000 seconds
  42. 42. 1’000’000 lines of code* 3 = 3’000’000 seconds/ 3600 = 833 hours
  43. 43. 1’000’000 lines of code* 3 = 3’000’000 seconds/ 3600 = 833 hours/ 8 = 104 days
  44. 44. 1’000’000 lines of code* 3 = 3’000’000 seconds/ 3600 = 833 hours/ 8 = 104 days/ 22 = 4.5 months
  45. 45. But, code is for the computer.Why would we ever read it?
  46. 46. forwardengineering}{}{}{}{
  47. 47. forwardengineeringactual development }{}{}{}{}{}{}{}{}{
  48. 48. forwardengineeringactual development }{}{}{}{}{}{}{}{}{
  49. 49. forwardengineeringactual development }{}{}{}{}{}{}{}{}{The only real documentation:the code!
  50. 50. Ward Cunningham, 1992technical debt.
  51. 51. When, due to constraints,I design quickly and dirty,my project gets loaded withWard Cunningham, 1992technical debt.
  52. 52. ?How can I controlthis...
  53. 53. You cannot controlwhat you cannot measure.Tom de Marco
  54. 54. 1Measuredesign2Assessdesign3Improvedesign
  55. 55. 1Measure design
  56. 56. Software metrics are measurements whichrelate to software systems, processes orrelated documents.
  57. 57. Metrics compress system traits into numbers.
  58. 58. Let’s see some examples...
  59. 59. Lorenz, Kidd, 1994Chidamber, Kemerer, 1994
  60. 60. Lorenz, Kidd, 1994Chidamber, Kemerer, 1994LOC - number of lines of codeCYCLO - cyclomatic complexity of a functionNOF - number of functionsFANOUT - outgoing coupling
  61. 61. NOA - number of attributesDIT - depth of inheritance treeTCC - tight class cohesionLorenz, Kidd, 1994Chidamber, Kemerer, 1994LOC - number of lines of codeCYCLO - cyclomatic complexity of a functionNOF - number of functionsFANOUT - outgoing coupling
  62. 62. ...
  63. 63. Examples of metric tools
  64. 64. Trouble in paradise...
  65. 65. Thresholds
  66. 66. What about software metrics?
  67. 67. Metric ValueLOC (lines of code) 8.000Would you maintain this system ?
  68. 68. Metric ValueLOC (lines of code) 8.000Would you maintain this system ?NOF (functions) 2
  69. 69. Metric ValueLOC (lines of code) 8.000Would you maintain this system ?NOF (functions) 2Changed your mind, right? ;-)
  70. 70. Metric ValueLOC 35175NOM 3618NOC 384CYCLO 5579NOP 19FANOUT 8590
  71. 71. Metric ValueLOC 35175NOM 3618NOC 384CYCLO 5579NOP 19FANOUT 8590?Are these numbers “normal” ?
  72. 72. We need means to compare.
  73. 73. We need comparable metrics.
  74. 74. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOOverview Pyramid provides a system’s overview.Marinescu, Lanza
  75. 75. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOSizeOverview Pyramid provides a system’s overview.Marinescu, Lanza
  76. 76. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOSize CommunicationOverview Pyramid provides a system’s overview.Marinescu, Lanza
  77. 77. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOSize CommunicationInheritanceOverview Pyramid provides a system’s overview.Marinescu, Lanza
  78. 78. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOSizeOverview Pyramid provides a system’s overview.Marinescu, Lanza
  79. 79. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOOverview Pyramid provides a system’s overview.Marinescu, Lanza
  80. 80. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOOverview Pyramid provides a system’s overview.Marinescu, LanzaMore numbers?!?
  81. 81. ...HIGH0.3016151090.25AVGC++450.20LOWJavaAVGLOW HIGH0.24101370.20100.1674NOM/NOCLOC/NOMCYCLO/LOC
  82. 82. ...HIGH0.3016151090.25AVGC++450.20LOWJavaAVGLOW HIGH0.24101370.20100.1674NOM/NOCLOC/NOMCYCLO/LOC4.000+OSS projects500.000.000+LOC
  83. 83. ...HIGH0.3016151090.25AVGC++450.20LOWJavaAVGLOW HIGH0.24101370.20100.1674NOM/NOCLOC/NOMCYCLO/LOC4.000+OSS projects500.000.000+LOC...and counting...
  84. 84. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOOverview Pyramid provides a system’s overview.Marinescu, Lanza
  85. 85. 0.31ANDCNOM20.21 190.1235175NOPNOC4180.158590LOC36189.425579NOMCALLS15128384FANOUT9.720.56AHHCYCLOOverview Pyramid provides a system’s overview.close to high close to average close to lowMarinescu, Lanza
  86. 86. Overview Pyramid provides a system’s overview.close to high close to average close to lowMarinescu, Lanza
  87. 87. But why do we measure?
  88. 88. We measure to control quality!
  89. 89. We measure to detect abnormalities!
  90. 90. 1Measuredesign2Assessdesign3Improvedesign
  91. 91. 2Assess design
  92. 92. Imagine changing just a small design fragment
  93. 93. 33%of all the classeswould require changesImagine changing just a small design fragment
  94. 94. Breaking design principles, rules and best practicesdeteriorates the code;it leads to design problems.
  95. 95. Are these bugs?
  96. 96. NO!
  97. 97. but...
  98. 98. Foutse et. al. - An exploratory study of the impact of anti-patterns on class change- and fault-proneness, 2012
  99. 99. Foutse et. al. - An exploratory study of the impact of anti-patterns on class change- and fault-proneness, 2012Classes participating in design problems aresignificantly more likely to be subject to changes andto be involved in fault-fixing changes (bugs)“”
  100. 100. GodClassBrainClassFeatureEnvyDataClassBrainMethodSignificantDuplicationIntensiveCouplingDispersedCouplingShotgunSurgeryTraditionBreakerRefusedParentBequestuseshasishashashas (partial)is partiallyhasisishasFutileHierarchyuseshashasishas (subclass)Riel, 1996Brown, 1998Fowler, 1999Marinescu, 2004Design Problems (anti-patterns)
  101. 101. How to detect design problems?
  102. 102. Use metrics!
  103. 103. Granularity of metrics
  104. 104. Metrics must be aggregated
  105. 105. Treat design problems as first-class entities
  106. 106. Let’s see an example...
  107. 107. God Classes tend to centralize the intelligence of thesystem, to do everything and to use data from smalldata-classes.A.Riel, 1996
  108. 108. God Classes tendto centralize the intelligence of the system,to do everything andto use data from small data-classes.
  109. 109. God Classescentralize the intelligence of the system,do everything anduse data from small data-classes.
  110. 110. God Classesare complex,are not cohesive,access external data.
  111. 111. God Classesare complex,are not cohesive,access external data.Compose metrics into queries usinglogical operators
  112. 112. Detection Strategies are metric-based queries todetect design flaws.METRIC 1 > Threshold 1Rule 1METRIC 2 < Threshold 2Rule 2AND Quality problemMarinescu
  113. 113. A God Class centralizes too much intelligence inthe system.ATFD > FEWClass uses directly more than afew attributes of other classesWMC ≥ VERY HIGHFunctional complexity of theclass is very highTCC < ONE THIRDClass cohesion is lowAND GodClassMarinescu
  114. 114. Envious Methods are more interested in data froma handful of classes.ATFD > FEWMethod uses directly more thana few attributes of other classesLAA < ONE THIRDMethod uses far more attributesof other classes than its ownFDP ≤ FEWThe used "foreign" attributesbelong to very few other classesAND Feature EnvyMarinescu, Lanza
  115. 115. Data Classes are dumb data holders.WOC < ONE THIRDInterface of class reveals datarather than offering servicesAND Data ClassClass reveals many attributes and isnot complexLanza, Marinescu 2006
  116. 116. Data Classes are dumb data holders.ANDORClass reveals manyattributes and is notcomplexNOAP + NOAM > FEWMore than a few publicdataWMC < HIGHComplexity of class is nothighNOAP + NOAM > MANYClass has many publicdataWMC < VERY HIGHComplexity of class is notvery highANDLanza, Marinescu 2006
  117. 117. 20+ Detection strategiesfor design flaws on class, method and subsystem level
  118. 118. !Demo timeinCode
  119. 119. ?Does anyone care design flaws
  120. 120. Time can tell
  121. 121. 63releases of Eclipse JDT and EMF
  122. 122. 2previousrelease9currentrelease7 3365DecayingClassRefactoredClassNewFlawedClass
  123. 123. 2previousrelease9currentrelease7 3365DecayingClassRefactoredClassNewFlawedClass
  124. 124. 2previousrelease9currentrelease7 3365DecayingClassRefactoredClassNewFlawedClass
  125. 125. 2previousrelease9currentrelease7 3365DecayingClassRefactoredClassNewFlawedClass
  126. 126. 2previousrelease9currentrelease7 3365DecayingClassRefactoredClassNewFlawedClass
  127. 127. 02468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7JDT EMFGodClassSchizophrenicClassRefusedParentBequestCodeDuplicationBlobOperationDataClumps
  128. 128. 02468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7JDT EMFGodClassSchizophrenicClassRefusedParentBequestCodeDuplicationBlobOperationDataClumps differentpatterns
  129. 129. 02468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7JDT EMFGodClassSchizophrenicClassRefusedParentBequestCodeDuplicationBlobOperationDataClumpsonlyflawedby birth
  130. 130. 02468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7JDT EMFGodClassSchizophrenicClassRefusedParentBequestCodeDuplicationBlobOperationDataClumpsstrongreactionto debt
  131. 131. 02468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468101.1 2 2.1 2.2 2.3 2.4 2.5 2.6 2.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.702468102 2.1 3 3.1 3.2 3.3 3.4 3.5 3.6 3.7JDT EMFGodClassSchizophrenicClassRefusedParentBequestCodeDuplicationBlobOperationDataClumpsonlypay-back
  132. 132. 1Measuredesign2Assessdesign3Improvedesign
  133. 133. 3Improve design
  134. 134. Let’s start with a simple example...
  135. 135. public class TarHeader{/** * The entrys name. */ public StringBuffer name; /** * The entrys permission mode. */ public int mode; /** * The entrys user id. */ public int userId; /** * The entrys group id. */ public int groupId;}
  136. 136. public class TarHeader{/** * The entrys name. */ StringBuffer name; /** * The entrys permission mode. */ int mode; /** * The entrys user id. */ int userId; /** * The entrys group id. */ int groupId;}publicpublicpublicpublic
  137. 137. public class TarHeader{/** * The entrys name. */ StringBuffer name; /** * The entrys permission mode. */ int mode; /** * The entrys user id. */ int userId; /** * The entrys group id. */ int groupId;}publicpublicpublicpublicDATACLASS
  138. 138. public class TarHeader{/** * The entrys name. */ StringBuffer name; /** * The entrys permission mode. */ int mode; /** * The entrys user id. */ int userId; /** * The entrys group id. */ int groupId;}
  139. 139. public class TarHeader{/** * The entrys name. */ StringBuffer name; /** * The entrys permission mode. */ int mode; /** * The entrys user id. */ int userId; /** * The entrys group id. */ int groupId;}privateprivateprivateprivate
  140. 140. public class TarHeader{/** * The entrys name. */ StringBuffer name; /** * The entrys permission mode. */ int mode; /** * The entrys user id. */ int userId; /** * The entrys group id. */ int groupId;}privateprivateprivateprivateEncapsulate public data(in TarHeader)1
  141. 141. but ...
  142. 142. Suddenly we have compile errors!
  143. 143. public class {public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset,TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset,TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset,TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset,TarHeader.GIDLEN );}TarEntry
  144. 144. public class {public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset,TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset,TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset,TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset,TarHeader.GIDLEN );}TarEntryTarHeader hdrhdr.namehdr.modehdr.userIdhdr.groupIdparseTarHeader
  145. 145. public class {public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset,TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset,TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset,TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset,TarHeader.GIDLEN );}TarEntryTarHeader hdrhdr.namehdr.modehdr.userIdhdr.groupIdparseTarHeaderMove the method(TarEntry > TarHeader)1
  146. 146. public class {public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset,TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset,TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset,TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset,TarHeader.GIDLEN );}TarEntryTarHeader hdrhdr.namehdr.modehdr.userIdhdr.groupIdparseTarHeaderEncapsulate public data(in TarHeader)2Move the method(TarEntry > TarHeader)1
  147. 147. but ...
  148. 148. public class TarEntry{public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );}public void writeEntryHeader(byte[] outbuf){ int offset = 0; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); long size = this.header.size; offset = TarHeader.getLongOctalBytes ( size, outbuf, offset, TarHeader.SIZELEN );}hdr.mode = (int)TarHeader.parseOctal( header,hdr.mode = (int)TarHeader.parseOctal( header,offset, TarHeader.MODELEN );offset, TarHeader.MODELEN );offset += TarHeader.MODELEN;offset += TarHeader.MODELEN;hdr.userId = (int)TarHeader.parseOctal( header,hdr.userId = (int)TarHeader.parseOctal( header,offset, TarHeader.UIDLEN );offset, TarHeader.UIDLEN );parseTarHeaderwriteEntryHeader
  149. 149. public class TarEntry{public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );}public void writeEntryHeader(byte[] outbuf){ int offset = 0; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); long size = this.header.size; offset = TarHeader.getLongOctalBytes ( size, outbuf, offset, TarHeader.SIZELEN );}hdr.mode = (int)TarHeader.parseOctal( header,hdr.mode = (int)TarHeader.parseOctal( header,offset, TarHeader.MODELEN );offset, TarHeader.MODELEN );offset += TarHeader.MODELEN;offset += TarHeader.MODELEN;hdr.userId = (int)TarHeader.parseOctal( header,hdr.userId = (int)TarHeader.parseOctal( header,offset, TarHeader.UIDLEN );offset, TarHeader.UIDLEN );parseTarHeaderwriteEntryHeaderDuplicatedCode
  150. 150. public class TarEntry{public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );}public void writeEntryHeader(byte[] outbuf){ int offset = 0; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); long size = this.header.size; offset = TarHeader.getLongOctalBytes ( size, outbuf, offset, TarHeader.SIZELEN );}hdr.mode = (int)TarHeader.parseOctal( header,hdr.mode = (int)TarHeader.parseOctal( header,offset, TarHeader.MODELEN );offset, TarHeader.MODELEN );offset += TarHeader.MODELEN;offset += TarHeader.MODELEN;hdr.userId = (int)TarHeader.parseOctal( header,hdr.userId = (int)TarHeader.parseOctal( header,offset, TarHeader.UIDLEN );offset, TarHeader.UIDLEN );parseTarHeaderwriteEntryHeaderExtract method(by factoring out the duplicated code)1
  151. 151. public class TarEntry{public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );}public void writeEntryHeader(byte[] outbuf){ int offset = 0; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); long size = this.header.size; offset = TarHeader.getLongOctalBytes ( size, outbuf, offset, TarHeader.SIZELEN );}hdr.mode = (int)TarHeader.parseOctal( header,hdr.mode = (int)TarHeader.parseOctal( header,offset, TarHeader.MODELEN );offset, TarHeader.MODELEN );offset += TarHeader.MODELEN;offset += TarHeader.MODELEN;hdr.userId = (int)TarHeader.parseOctal( header,hdr.userId = (int)TarHeader.parseOctal( header,offset, TarHeader.UIDLEN );offset, TarHeader.UIDLEN );parseTarHeaderwriteEntryHeaderExtract method(by factoring out the duplicated code)1Move the newly created method(in TarHeader)2
  152. 152. public class TarEntry{public void parseTarHeader( TarHeader hdr, byte[] header ){ int offset = 0; hdr.name = TarHeader.parseName( header, offset, TarHeader.NAMELEN ); offset += TarHeader.NAMELEN; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); offset += TarHeader.UIDLEN; hdr.groupId = (int)TarHeader.parseOctal( header, offset, TarHeader.GIDLEN );}public void writeEntryHeader(byte[] outbuf){ int offset = 0; hdr.mode = (int)TarHeader.parseOctal( header, offset, TarHeader.MODELEN ); offset += TarHeader.MODELEN; hdr.userId = (int)TarHeader.parseOctal( header, offset, TarHeader.UIDLEN ); long size = this.header.size; offset = TarHeader.getLongOctalBytes ( size, outbuf, offset, TarHeader.SIZELEN );}hdr.mode = (int)TarHeader.parseOctal( header,hdr.mode = (int)TarHeader.parseOctal( header,offset, TarHeader.MODELEN );offset, TarHeader.MODELEN );offset += TarHeader.MODELEN;offset += TarHeader.MODELEN;hdr.userId = (int)TarHeader.parseOctal( header,hdr.userId = (int)TarHeader.parseOctal( header,offset, TarHeader.UIDLEN );offset, TarHeader.UIDLEN );parseTarHeaderwriteEntryHeaderExtract method(by factoring out the duplicated code)1Move the newly created method(in TarHeader)2Encapsulate public data(in TarHeader)3
  153. 153. there is also an alternative solution ...
  154. 154. Move data(TarHeader > TarEntry)1
  155. 155. Move data(TarHeader > TarEntry)1Encapsulate public data(in TarEntry)2
  156. 156. vs.Extract method(out of the duplicated code)1Move the newly created method(in TarHeader)2Encapsulate public data(in TarHeader)3Move data(TarHeader > TarEntry)1Encapsulate public data(in TarEntry)2
  157. 157. vs.Which solution is best?Extract method(out of the duplicated code)1Move the newly created method(in TarHeader)2Encapsulate public data(in TarHeader)3Move data(TarHeader > TarEntry)1Encapsulate public data(in TarEntry)2
  158. 158. Only the engineer candecide!
  159. 159. Three lessons...
  160. 160. Correction implies understanding the whole contextContextual1
  161. 161. Correction involves the decision of the engineerDecisional2
  162. 162. We need toolsAutomated3
  163. 163. We need multiple instrumentsto explore...
  164. 164. !Demo timeinCode
  165. 165. There are many ways to explore...
  166. 166. ...but the best way is....
  167. 167. to see
  168. 168. 1854,London,choleraepidemic
  169. 169. 1854,London,choleraepidemic
  170. 170. We arevisualbeings...and we’re good atspotting patterns
  171. 171. Gestalt principlesproximityenclosure connectivitysimilarity
  172. 172. PreattentiveProcessing
  173. 173. Let me demonstrate that!
  174. 174. In 7 seconds count numbers larger than 0.85!0.103 0.176 0.387 0.300 0.829 0.276 0.179 0.321 0.192 0.2500.333 0.384 0.864 0.587 0.857 0.698 0.640 0.621 0.984 0.3160.421 0.309 0.654 0.729 0.228 0.529 0.832 0.435 0.699 0.4261.266 0.750 0.056 0.936 0.711 0.749 0.723 0.201 0.542 0.8190.225 0.926 0.643 0.337 0.721 0.337 0.682 0.987 0.232 0.4490.187 0.586 0.529 0.340 0.276 0.835 0.473 0.445 1.103 0.7201.153 0.485 0.560 0.428 0.628 0.335 0.456 0.879 0.699 0.424
  175. 175. What about now?0.103 0.176 0.387 0.300 0.829 0.276 0.179 0.321 0.192 0.2500.333 0.384 0.864 0.587 0.857 0.698 0.640 0.621 0.984 0.3160.421 0.309 0.654 0.729 0.228 0.529 0.832 0.435 0.699 0.4261.266 0.750 0.056 0.936 0.711 0.749 0.723 0.201 0.542 0.8190.225 0.926 0.643 0.337 0.721 0.337 0.682 0.987 0.232 0.4490.187 0.586 0.529 0.340 0.276 0.835 0.473 0.445 1.103 0.7201.153 0.485 0.560 0.428 0.628 0.335 0.456 0.879 0.699 0.424
  176. 176. What about now?0.103 0.176 0.387 0.300 0.829 0.276 0.179 0.321 0.192 0.2500.333 0.384 0.864 0.587 0.857 0.698 0.640 0.621 0.984 0.3160.421 0.309 0.654 0.729 0.228 0.529 0.832 0.435 0.699 0.4261.266 0.750 0.056 0.936 0.711 0.749 0.723 0.201 0.542 0.8190.225 0.926 0.643 0.337 0.721 0.337 0.682 0.987 0.232 0.4490.187 0.586 0.529 0.340 0.276 0.835 0.473 0.445 1.103 0.7201.153 0.485 0.560 0.428 0.628 0.335 0.456 0.879 0.699 0.424Pre-attentive features!
  177. 177. Why use pictures in software?
  178. 178. Remember...1’000’000 lines of code* 3 = 3’000’000 seconds/ 3600 = 833 hours/ 8 = 104 days/ 22 = 4.5 months
  179. 179. A picture is wortha thousand words.Proverb
  180. 180. Software visualization is more than UML!
  181. 181. PolymetricViews
  182. 182. PolymetricViews show up to 5 metrics.ColormetricWidth metricHeight metricPosition metricsLanza, 2003
  183. 183. Example 1: System ComplexityView
  184. 184. System Complexity shows class hierarchies.linesattributesmethodsLanza, Ducasse, 2003
  185. 185. Compresses 1.300 classes in one picture.
  186. 186. Compresses 1.300 classes in one picture.
  187. 187. Example 2: Code City
  188. 188. Code City shows where your code lives.Wettel, Lanza, 2007classes are buildings grouped in quarters of packages
  189. 189. Look carefully how the system evolves in time!
  190. 190. Look carefully how the system evolves in time!
  191. 191. Trouble in paradise...
  192. 192. Heterogeneity
  193. 193. They are simply too many...
  194. 194. Edges
  195. 195. They are simply too many...
  196. 196. Beyond polymetric views...
  197. 197. Polymetric Maps
  198. 198. Polymetric Mapsdisplay various design concerns, but reuse the layout!
  199. 199. Polymetric Mapsdisplay various design concerns, but reuse the layout!...and no edges!
  200. 200. Example #1: Package Map
  201. 201. Remember this one?
  202. 202. Package Map: the layoutEclipse-JDT, 2010
  203. 203. Package Map: design problemsEclipse-JDT, 2010severenoaffected by design problems
  204. 204. Package Map: coupling perspectiveEclipse-JDT, 2010client (uses other classes)provider (is used by other classes)manymanynonenone
  205. 205. Eclipse-JDT, 2010Package Map: coupling perspective
  206. 206. Eclipse-JDT, 2010Interactive!Package Map: coupling perspective
  207. 207. Example #2: Hierarchy Map
  208. 208. Multiple Inheritance ?
  209. 209. Multiple Inheritance ?Interfaces?
  210. 210. Multiple Inheritance ?Interfaces?
  211. 211. severenoaffected by design problems
  212. 212. client (uses other classes)provider (is used by other classes)manymanynonenone
  213. 213. 11.000+ classes in one picture...Java JDK 1.5, 2011
  214. 214. A picture is wortha thousand words.Proverb
  215. 215. A demo is wortha thousand pictures.Radu
  216. 216. !Demo timeinCode
  217. 217. inCodeintooitus.com/products/incode

×