250 likes | 448 Views
Investigating the Evolution of Bad Smells in Object-Oriented Code Alexander Chatzigeorgiou Anastasios Manakos University of Macedonia Thessaloniki, Greece. 7th Int. Conference on the Quality of Information and Communications Technology ( QUATIC’ 2010). Design Problems.
E N D
Investigating the Evolution of Bad Smells in Object-Oriented Code Alexander Chatzigeorgiou Anastasios Manakos University of Macedonia Thessaloniki, Greece 7th Int. Conference on the Quality of Information and Communications Technology (QUATIC’ 2010)
Design Problems non-compliance with design principles excessive metric values violations of design heuristics lack of design patterns Fowler’s bad smells
Software Ageing well-designed code Design quality decays
Goal • To employ past source code data in order to investigate the evolution of design problems • Focus is on the problems rather than the refactorings • Shed light on questions such as: • Does the number of problems increase over time ? • Are problems solved only after targeted activities ? • Do smells appear during software evolution ? • How frequent are refactoring activities ? • How urgent is it to remove the identified smells ?
Context • Two open source projects: • JFlex (10 versions) • JFreeChart (14 versions) • Detection tool: JDeodorant • Identified smells: • Long Method • Feature Envy • State Checking
Long Method Pieces of code with large size, high complexity and low cohesion int i; int sum = 0; for(i = 0; i < N; ++i) { sum = sum + i; } System.out.println(sum); int i; int product = 1; for(i = 0; i < N; ++i) { product = product *i; } System.out.println(product);
Feature Envy A method is “more interested in a class other than the one it actually is in” Target Source m1() m2() m3() m(Target t) { t.m1(); t.m2(); t.m3(); } m() { m1(); m2(); m3(); }
State Checking type State Checking manifests itself as conditional statements that select an execution path based on the state of an object StateB StateA Context Context Type • + method() { • } • + method() { • type.method(); • } +method() { } +method() { } +method() - type : int -STATE_A : int = 1 -STATE_B : int = 2 - type : int -STATE_A : int = 1 -STATE_B : int = 2 • switch(type) { • case STATE_A: • break; • case STATE_B: • break; • } • doStateA(); • doStateB();
Long Method JFlex
Elimination of smells: Reasons • Code Rewriting → Accidental Elimination • Code Removal → Unintentional Elimination • Class/Method Removal → Unintentional Elimination • Intentional Refactoring Activity: • Long Method: Extract method refactoring has been applied • Feature Envy: Suffering method is moved to the target class • State Checking: Polymorphism has been introduced
Categories Α Β1 Smell appears Method is introduced Β2 C1 C2 D1 D2 D3 D4
Results JFlex Long Method • 90% extend up to the latest version • 10% disappear during the course of the project • 3.33% smell removal • no case can be regarded as application of refactoring
Results JFreeChart Long Method ~79% extend up to the latest version ~60% exist from the beginning → design problems are also a consequence of inefficient OOAD • 7.24% explicit smell removal • only three cases of unambiguous Extract Method
Results ~75% ~40% ~15%
Average Time of Persistence • A value of 100% would indicate that the smell exists throughout all examined versions some smells are more common and have longer persistence → warrant more attention
Unambiguously Identified Refactorings Out of 648 cases, only in 5 a refactoring activity was undertaken to remove the smell • Possible Reasons: • Designers perform refactoring based on subjective perception • Limited support by CASE tools to identify non-trivial smells
Active Bad Smells Are all identified design problems important ? Example: Why would it be urgent to improve a method suffering from Long Method if the method had never been changed? Need to define (quantify) the urgency to resolve a problem One possible source of information: Past code versions Underlying Assumption: Code fragments that have been subject to maintenance in that past are more likely to undergo changes Active Bad Smell: A design problem where the affected code has been the subject of maintenance, at least once.
What to look for Long Method: its presence implies that it might be difficult to maintain the method → perform refactoring if we expect that the method will change Previous versions: detect changes in the implementation of the method change
What to look for Feature Envy: is related to the access of foreign members → perform refactoring if we expect that the total number of accesses to foreign members will change Previous versions: detect changes in the number of accesses to foreign members Target Source m1() m2() m3()
What to look for State Checking: implies a missed opportunity for polymorphism State StateA StateB StateC if (state == StateA) { . . . . . . } else if (state == StateB) { . . . . . . } else if (state == StateC) { . . . . . . } + . . . . . . . . . (additional statements) + . . . . . . . . .
Results JFreeChart State Checking
Results – Percentage of Active Smells Significantly smaller number of smells is alarming Long Method Larger percentage of active smells Larger total number Longer persistence →maintenance effort should prioritize them
Conclusions • Source code history tells us: • Design problems accumulate as projects mature • A significant percentage of problems are present from the beginning • Very few smells are removed due to refactorings • Refactoring identification and suggestion can be made more accurate and meaningful • Compare the evolution of smells with the results of tools that identify applied refactorings
Thank you for your attention 7th Int. Conference on the Quality of Information and Communications Technology (QUATIC’ 2010)