Transcript Document

Software Restructuring(Refactoring)

Giriprasad Sridhara CISC 879 Spring 2007 May 10 2007 1

Road Map

• In this class • Basics of refactoring • Relation with – Performance optimization – Compiler optimization – Unit Tests • Identifying refactoring opportunities • Refactoring catalog 2

Road Map

• Learning cannot be vicarious – So a small refactoring game!

• Challenges in refactoring • When to refactor?

• Benefits of refactoring • Drawbacks of refactoring • Next class • Demo with Eclipse • Demo with Visual Studio 3

Road Map

• Eclipse plug-in to – Do your own refactoring • Examples of refactorings – In real world code • JHotDraw • Struts • Eclipse UI component 4

Refactoring

• Modification of code so as to: – Improve internal structure – Preserve external functionality • Not necessarily to – Fix bugs OR – Add new functionality – But to improve code understandability 5

Phases of software development

• Waterfall model (?) – Analysis – Design – Coding – Testing (unit and integration) – Maintenance • Which is the most expensive phase (?) – Maintenance – Consumes 60-90% of the overall resources!

6

Software Maintenance

• Maintenance(?) – making corrections to fix bugs – making changes to incorporate new features – Consumes maximum resources in software development life cycle • Time and People  Money (Millions of dollars!) • Maintenance leitmotif – Understanding existing code AND – Making changes.

7

Refactoring

• If it ain’t broke, don’t fix it!

– So Why Refactor? (?) • Helps in software maintenance • As it makes the code – easier to understand – hence easier to make changes.

8

Behavior preservation

• We keep saying refactoring preserves external behavior • But, what exactly is meant by it? (?) • Opdyke defined it as: – For the same set of input values, – The set of output values should be the same • before and after the refactoring.

• Is this definition sufficient? (?) • For real time systems etc – We can add the following: • Performance of the program – i.e. execution time. • Memory requirements 9

Refactoring (What constitutes it and what does not?)

• Consider an example: • We are searching for an item in a huge

ordered

list of items. • Suppose the program uses the recursive version of binary search for this task. • Replacing the binary search with the simpler linear search – IS it refactoring? (?) – NO!

– This is because the performance of the program in the worst case has degenerated. 10

Refactoring (What constitutes it and what does not?)

• Replacing the recursive version of binary search with an iterative version – Is it refactoring? (?) – YES – If the developers are more comfortable with non recursive implementations. • Replacing our own implementation of binary search with a proven available implementation from a library (like C++ STL) – Is it refactoring? (?) – YES – Because the maintenance effort is reduced.

11

Refactoring (What constitutes it and what does not?)

• Conclusion: – Simply replacing a more complicated piece of code with supposedly simpler code – Say, replacing a more complex algorithm with a simple algorithm – is NOT refactoring.

12

Example (Before refactoring)

void CnvrtTemp() { // Get the user input cout << "Please enter the temperature " << endl; double d1 =0; cin >> d1; // Convert Fahrenheit to Celsius double d2 = (d1 - 32) * 5.0/9.0; cout << "Converted temperature is " << d2 << endl; } 13

Example (After refactoring) void ConvertTemperature() { double Fahrenheit = GetUserInput(); cout << "Converted temperature is " << ConvertFahrenheitToCelsius(Fahrenheit) << endl; } double GetUserInput() { cout << "Please enter the temperature " << endl; double Fahrenheit =0; cin >> Fahrenheit; return Fahrenheit; } double ConvertFahrenheitToCelsius(double Fahrenheit) { const int OFFSET = 32; const double CONVERSION_FACTOR = 5.0/9; double Celsius = (Fahrenheit - OFFSET) * CONVERSION_FACTOR; return Celsius; } 14

Refactoring vs Performance Optimization

• Performance optimization (?) – Changes done to code to improve the performance – i.e. execution time (and memory consumption) • May make the code harder to comprehend, while improving the performance.

• For example, – Simple versus more complicated but performant algorithm. – Insertion sort with Quick Sort – Due to this, • the code may have become harder to understand and modify, • but it is not the primary concern of performance optimization.

• Refactoring on the other hand – does not change the observable behavior at all, – tries to improve the internal structure so that – The code is easier to understand and modify later on.

15

Refactoring vs Compiler Optimization

• Compiler optimization (?) – Changes done by the compiler – To optimize the code • to improve the performance • i.e. execution time (and memory consumption) – Changes done at the back-end i.e. Intermediate Representation or Machine Level – Go to example in Eclipse … • Refactoring – Changes done at the front end i.e. source code level.

16

Refactoring and Unit Tests

• Relationship between refactoring and Unit tests (?) • Refactoring is strongly good suite of unit tests dependent on having a • With the unit tests, we can refactor • Then run the automated tests – To verify that the behaviour is indeed preserved.

• Without good unit tests, – developers may shy away from refactoring – Due to the fear that they may break something.

17

Identifying refactoring opportunities (Code smell)

• By

bad smells

in code • Duplicated code • Poorly named entities • Long Method • Large (God) class • Long parameter list • Comments • Switch statements 18

Identifying refactoring opportunities (Code smell)

• Data clumps • Middle man • Inappropriate intimacy • Primitive obsession • Lazy class • Message chains • Show example in Eclipse … 19

Classification of Refactorings

• Extract Method • Rename Method • Replace magic number with symbolic constant • Pull Up Method • Form Template Method • Remove Parameter 20

Classification of Refactorings

• Eliminate unused return value • Replace conditional with polymorphism • Introduce explaining variable • Move Method • Replace error code with exception • Encapsulate field (no public variables) • Consolidate duplicate conditional fragments • Show example in Eclipse … 21

Refactoring Game

• A small example to illustrate refactoring – Detect smells – Identify the applied refactorings – Please see the hand-out sheets one by one • Subsequent sheets have the answer!

– Should take about 5 minutes.

– Does NOT count towards your final grade!

22

Some other Refactorings

• Discuss only if time permits • Encapsulate collection – Don’t return vector or list, return iterator • Replace inheritance with delegation – Stack derived from vector in Java 1.1

– Liskov Substitution Principle 23

Challenges in Refactoring

• What do you think are the major challenges in refactoring research? (?) • Which code to refactor?

– i.e. identify the bad smell.

– Depends on human intuition – Very subjective – CCFinder, DAIKON • OK, we found that we could apply some refactorings to code.

– Does the order of applying these matter? (?) – Are there dependencies between a set of refactorings?

– Tom Mens et al AGG 24

Challenges in Refactoring

• Say, we are looking at a version control system and difference between 2 versions.

• Which of the code changes are due to refactorings?

– Why all would code have changed? (?) • Due to bug fix • Due to new feature addition • Due to genuine refactoring – Weissberger et al (signature and clone based) • Correctness of refactored code – JUNGL 25

Challenges in Refactoring

• Reconciling test cases – Code changes due to refactoring – How to identify new test cases • Say, for, Extract Method – How to identify redundant test cases • Say, we removed, duplicated code.

• Reconciling with other artifacts – Design documents… 26

A time to refactor

• When should we refactor? (?) • Commonly accepted wisdom (heuristics): • When we add new functionality • When we fix a bug • When we do a code review.

27

Benefits of refactoring

• Software design improvement: (How does it help?) – A primary casualty of bug fixes and feature enhancements in software, is • design of the software – By refactoring, we can ensure that the design does not decay.

• Making software easier to understand: (?) – As has been stated previously, this is the primary aim and benefit of refactoring.

• Finding bugs: (?) – As we refactor code, we would be looking at it deeply to find refactoring opportunities. – During this process we could also uncover dormant bugs in the code and fix them.

28

Refactoring problems and limitations

• What do you think are problems and limitations of refactoring? (?) • Databases: – Many applications have code that is tightly coupled with an underlying database schema. – The code and the database are usually managed by different people.

– Due to these factors, it is difficult to refactor enterprise database applications, – But, they constitute a substantial chunk of the software market – So we need effective refactoring techniques here.

29

Refactoring problems and limitations

• Interfaces: – Refactoring techniques like RenameMethod – change a published interface. – This problem can occur when we want to refactor library code – but we are hampered by the fact that some portions of it are published interfaces – And thus cannot be refactored so easily,(Why?) – Because that would break the client code.

30

Source of this presentation

• Refactoring Book – Martin Fowler • Bill Opdyke – Ph.D Thesis • Don Roberts – Ph.D Thesis • Tom Mens – Refactoring survey • Wikipedia 31

Want to do research in refactoring?

• Check out the following: – University of Illinois, Urbana-Champaign – Ralph Johnson • Tom Mens et al 32

Questions?

Thank you.

33