(slides courtesy of Tudor Girba - Uni. Bern www.tudorgirba.com)
Herodotus Herodotus displays his enquiry, so that human achievements may not become forgotten and great and marvelous deeds may not be without their glory especially to show why the two peoples fought with each other. r e v e r s e
e n g i n e e r i n g f o r w a r d
e n g i n e e r i n g } { } { } { } { } { } { } { } { } { actual development r e v e r s e
e n g i n e e r i n g f o r w a r d
e n g i n e e r i n g } { } { } { } { } { } { } { } { } { actual development r e v e r s e
e n g i n e e r i n g History holds useful information History holds useful information When did it change? Lehman etal, 2001 History holds useful information When did it change? How did it change? Lanza, Ducasse, 2002 Evolution Matrix shows changes in classes Idle class Pulsar class Supernova class White dwarf class History holds useful information When did it change? How did it change? History holds useful information When did it change? How did it change? What changed? 2 4 3 5 7 2 2 3 4 9 2 2 1 2 3 2 2 2 2 2 1 5 3 4 4 1 5 3 4 4 4 2 1 0 + + + = 7 = LENOM(C) = ! |NOMi(C)-NOMi-1(C)| 2 i-n Evolution of Number of Methods LENOM(C) 1 5 3 4 4 LENOM(C) = ! |NOMi(C)-NOMi-1(C)| 2 i-n LENOM(C) 4 2 -3 2 2 -2 1 2 -1 0 2 0 + + + = 1.5 = EENOM(C) = ! |NOMi(C)-NOMi-1(C)| 2 2-i Latest Evolution of Number of Methods Earliest Evolution of Number of Methods EENOM(C) 4 2 0 2 2 -1 1 2 -2 0 2 -3 + + + = 5.25 = ENOM LENOM EENOM 7 3.5 3.25 7 5.75 1.37 3 1 2 0 0 0 7 1.5 5.25 2 4 3 5 7 2 2 3 4 9 2 2 1 2 3 2 2 2 2 2 1 5 3 4 4 ENOM LENOM EENOM 7 3.5 3.25 7 5.75 1.37 3 1 2 0 0 0 7 1.25 5.25 balanced changer late changer dead stable early changer Evolution Stability Historical Max Growth Trend ... Number of Methods Number of Lines of Code Cyclomatic Complexity Number of Modules ... of History can be measured in many ways Detection Strategies are metric-based queries to detect design aws METRIC 1 > Threshold 1 Rule 1 METRIC 2 < Threshold 2 Rule 2 AND Quality problem e.g., a God Class centralizes too much intelligence ATFD > FEW Class uses directly more than a few attributes of other classes WMC ! VERY HIGH Functional complexity of the class is very high TCC < ONE THIRD Class cohesion is low AND GodClass B u t , w h a t if it is s t a b le ? Ratiu etal, 2004 AND isGodClass(last) God Class in the last version Stability > 90% Stable throughout the history Harmless God Class History holds useful information When did it change? How did it change? What changed? History holds useful information When did it change? How did it change? What changed? What will change? Common wisdom The recently changed parts are likely to change in the near future A re they really? 30% 90% present past future prediction hit present past future YesterdayWeatherHit(present): prediction hit past:=histories.topLENOM(start, present) future:=histories.topEENOM(present, end) past.intersectWith(future) .notEmpty() Girba etal, 2004 Yesterdays Weather shows the locality of changes hit hit hit YW = 3 / 8 = 37% hit hit hit hit hit hit hit YW = 7 / 8 = 87% History holds useful information When did it change? How did it change? What changed? What will change? History holds useful information When did it change? How did it change? What changed? What will change? Who did what? CVS shows activity Who is responsible for this? Who is responsible for this? Alphabetical order is no order Ownership Map reveals development patterns Girba etal, 2006 JEdit Ant (john 23.06.03) public boolean stillValid (ToDoItem I, Designer dsgr) { (bill 09.01.05) if (!isActive()) { (bill 09.01.05) return false (bill 09.01.05) } (steve 16.02.05) List offs = i.getOffenders(); (john 23.06.03) Object dm = offs.firstElement(); (steve 16.02.05) ListSet newOffs = computeOffenders(dm); (john 23.06.03) boolean res = offs.equals(newOffs); (john 23.06.03) return res; (george 13.02.05) public boolean stillValid (ToDoItem I, Designer dsgr) { (bill 11.13.05) if (!isActive()) { (bill 11.13.05) return false (bill 11.13.05) } (steve 16.02.05) List offs = i.getOffenders(); (george 13.02.05) Object dm = offs.firstElement(); (steve 16.02.05) ListSet newOffs = computeOffenders(dm); (george 13.02.05) boolean res = offs.equals(newOffs); (george 13.02.05) return res; Who copied from whom? (john 23.06.03) public boolean stillValid (ToDoItem I, Designer dsgr) { (bill 09.01.05) if (!isActive()) { (bill 09.01.05) return false (bill 09.01.05) } (steve 16.02.05) List offs = i.getOffenders(); (john 23.06.03) Object dm = offs.firstElement(); (steve 16.02.05) ListSet newOffs = computeOffenders(dm); (john 23.06.03) boolean res = offs.equals(newOffs); (john 23.06.03) return res; (george 13.02.05) public boolean stillValid (ToDoItem I, Designer dsgr) { (bill 11.13.05) if (!isActive()) { (bill 11.13.05) return false (bill 11.13.05) } (steve 16.02.05) List offs = i.getOffenders(); (george 13.02.05) Object dm = offs.firstElement(); (steve 16.02.05) ListSet newOffs = computeOffenders(dm); (george 13.02.05) boolean res = offs.equals(newOffs); (george 13.02.05) return res; Who copied from whom? 13.02.05 public boolean stillValid (ToDoItem I, Designer dsgr) { 11.13.05 if (!isActive()) { 11.13.05 return false 11.13.05 } 16.02.05 List offs = i.getOffenders(); 13.02.05 Object dm = offs.firstElement(); 16.02.05 ListSet newOffs = computeOffenders(dm); 13.02.05 boolean res = offs.equals(newOffs); 13.02.05 return res; 23.06.03 public boolean stillValid (ToDoItem I, Designer dsgr) { 09.01.05 if (!isActive()) { 09.01.05 return false 09.01.05 } 16.02.05 List offs = i.getOffenders(); 23.06.03 Object dm = offs.firstElement(); 16.02.05 ListSet newOffs = computeOffenders(dm); 23.06.03 boolean res = offs.equals(newOffs); 23.06.03 return res; When did changes happen? Clone Evolution shows how developers copy Balint etal, 2006