Investigating the Evolution of Bad Smells in Object-Oriented Code Alexander Chatzigeorgiou...

25
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)
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    218
  • download

    0

Transcript of Investigating the Evolution of Bad Smells in Object-Oriented Code Alexander Chatzigeorgiou...

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

lack of design patterns

violations of design heuristics

Fowler’s bad smells

Software Ageing

Design quality decays

well-designed code

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

int i; int product = 1; for(i = 0; i < N; ++i) { product = product *i; }

System.out.println(product);

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);

Feature Envy

A method is “more interested in a class other than the one it actually is in”

m(Target t) { t.m1(); t.m2(); t.m3();}

m() { m1(); m2(); m3();}

State Checking

State Checking manifests itself as conditional statements that select an execution path based on the state of an object

doStateA();

switch(type) {case STATE_A:

break;case STATE_B:

break;}

doStateB();

Total Number of Smells

0102030405060708090

1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4 1.4.1 1.4.2 1.4.3

Num

ber o

f Sm

ells

Versions

JFlex

Long Method

Feature Envy

State Checking

050

100150200250300350400

Num

ber o

f Sm

ells

Versions

JFreeChart

Long Method

Feature Envy

State Checking

Long Method

1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4 1.4.1 1.4.2 1.4.3

Versions

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

Versions

Α

Β1

Β2

C1

C2

D1

D2

D3

D4

Method is introduced

Smell appears

Results

JFlex

Long Method

1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4 1.4.1 1.4.2 1.4.3

Versions

C1 (2.22%)

C2 (6.66%)

B1 (18.88%)

B2 (13.33%)

D3 (1.11%)

-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

Versions

C1 (1.31%)

C2 (3.93%)

Β1 (27.07%)

Β2 (47.16%)

D1 (8.29%)

D2 (1.96%)

D3 (4.14%)

D4 (1.52%)

A (4.58%)

Results

Smell Categories

JFlex JFreeChartLong

MethodFeature Envy

State Checking

Long Method

Feature Envy

State Checking

A 52

57.77%836.36%

360.0%

214.58%

714.0%

B1

1718.88%

313.63%

120.0%

12427.07%

521.73%

510.0%

B2

1213.33%

522.72%

120.0%

21647.16%

313.04%

2346.0%

C1

22.22%

522.72%

61.31%

36.0%

C2

66.66%

14.54%

183.93%

14.34%

510.0%

D1

388.29%

14.34%

612.0%

D2

91.96%

28.69%

D3

11.11%

194.14%

1147.82%

12.0%

D4

71.52%

Total Number of Distinct Smell

Cases90 22 5 458 23 50

~75%

~15%

~40%

Average Time of Persistence

• A value of 100% would indicate that the smell exists throughout all examined versions

JFlex JFreeChart

Long Method

Feature Envy

State Checking

Long Method

Feature Envy

State Checking

77% 68% 68% 40% 28% 57%

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

JFlex JFreeChartLong

MethodFeature Envy

State Checking

Long Method

Feature Envy

State Checking

0 (0.00%)

1 (4.54%)

0 (0.00%)

3 (0.65%)

1 (4.34%)

0 (0.00%)

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

What to look for

State Checking: implies a missed opportunity for polymorphism

if (state == StateA) { . . . . . .}else if (state == StateB) { . . . . . .}else if (state == StateC) { . . . . . .}

+. . .. . .. . .

+ (additional statements)

. . .

. . .

. . .

Results

JFreeChart

State Checking

0.5.6 0.6.0 0.7.0 0.7.1 0.7.2 0.7.3 0.7.4 0.8.0 0.8.1 0.9.0

Versions

0.9.1 0.9.2 0.9.3 0.9.4a

Δ

Δ

ΔΔ

Δ

Δ Δ Δ

Δ

Δ

Δ Δ Δ

Δ Δ ΔΔ

Δ Δ Δ

Δ Δ Δ

Δ Δ ΔΔ

Δ Δ

Δ Δ

Δ Δ

Δ Δ Δ Δ Δ Δ

Δ Δ Δ Δ Δ Δ

Δ Δ Δ Δ Δ Δ

Δ Δ Δ Δ Δ Δ

Δ Δ Δ

Δ Δ Δ

Δ Δ Δ Δ

Δ Δ Δ Δ

Δ Δ Δ Δ Δ Δ

Δ Δ Δ ΔΔ

Δ Δ

Δ Δ

Results – Percentage of Active Smells

Significantly smaller number of smells is alarming

JFlex JFreeChartLong

MethodFeature Envy

State Checking

Long Method

Feature Envy

State Checking

5358.89%

627.27%

120%

28562.23%

00%

2652%

Long Method Larger percentage of active smells Larger total number Longer persistence

→ maintenance effort should prioritize them

Conclusions

Source code history tells us:

1. Design problems accumulate as projects mature

2. A significant percentage of problems are present from the beginning

3. Very few smells are removed due to refactorings

4. 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)