0% found this document useful (0 votes)
18 views33 pages

CH 24

The document discusses refactoring, which is the process of restructuring existing code without changing its external behavior. It aims to improve code quality by making code easier to understand and modify. Some reasons for refactoring include duplicated code, long routines, poor naming, and tight coupling between classes. Specific refactoring techniques are organized into data-level, statement-level, routine-level, class implementation, class interface, and system-level categories. Refactoring safely requires saving the original code, keeping changes small and isolated, and testing after each small refactoring.

Uploaded by

Ateeqa Kokab
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views33 pages

CH 24

The document discusses refactoring, which is the process of restructuring existing code without changing its external behavior. It aims to improve code quality by making code easier to understand and modify. Some reasons for refactoring include duplicated code, long routines, poor naming, and tight coupling between classes. Specific refactoring techniques are organized into data-level, statement-level, routine-level, class implementation, class interface, and system-level categories. Refactoring safely requires saving the original code, keeping changes small and isolated, and testing after each small refactoring.

Uploaded by

Ateeqa Kokab
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 33

Chapter 24:

Refactoring

Group members:
Ayeza Hassan 20011598-112
Ayesha Ali 20011598-113
M Abdullah 20011598-122
Now presenting

AYESHA ALI
20011598-113
Software Evolution:

• Developers continuously modify, enhance and adopt software to new requirements.


• Software evolves with time and deviates from its intended design.
• As software further evolves , it deviates from its original design.
1. Decreased understandability: It becomes more difficult to understand a
software and becomes less maintainable.
2. Decreased reliability: Reliability of software decreases as it deviates from its
original design and documentation become out of date.
3. Increased maintenance cost: The cost of maintaining the software rises in the
absence of preventive measures.
• Therefore , there is a need to decrease the complexity of software by improving its
internal quality.
Refactoring:

• The key strategy in achieving The Cardinal Rule of Software Evolution is refactoring.
• “A change made to the internal structure of the software to make it easier to
understand and cheaper to modify without changing its observable behavior”.
• Reorganizing a software to give it a different look or structure.
• Decomposing a program into its constituent parts as much as possible.
• Refactoring is done in order to make a software:
• Easier to understand
• Easier to change
• Easier to update documentation
• Less vulnerable to faults when changes or made in future
Reasons to refactoring:
Sometimes code degenerates under maintenance, and sometimes the code just wasn’t very good in the first
place. In either case, here are some warning signs sometimes called “smells” that indicate where refactorings
are needed:

1. Code is duplicated:
Duplicated code almost always represents a failure to fully factor the design in the first place. Duplicate code
sets you up to make parallel modifications—whenever you make changes in one place, you have to make
parallel changes in another place.
2.A routine is too long:
In object-oriented programming, longer routines are rarely needed. One way to improve a system is to increase
its modularity—increase the number of well-defined, well-named routines that do one thing and do it well.
When changes lead you to revisit a section of code, take the opportunity to check the modularity of the
routines in that section. If a routine would be cleaner if part of it were made into a separate routine, create a
separate routine.
Reasons to refactoring:

3. A loop is too long or too deeply nested:


Loop innards tend to be good for being converted into routines, which helps to better
factor the code and to reduce the loop’s complexity.
4. A class has poor cohesion:
If you find a class that as a mixture of unrelated responsibilities, that class should be
broken up into multiple classes, each of which has responsibility for a cohesive set of
responsibilities.
5. A routine has a poor name:
If a routine has a poor name, change the name of the routine where it’s defined, change
the name in all places it’s called, and then recompile. As hard as it might be to do this
now, it will be even harder later, so do it as soon as you notice it’s a problem.
Reasons to refactoring:

6. A class interface does not provide a consistent level of abstraction:


Even classes that begin with a cohesive interface can lose their original consistency. Class
interfaces tend to morph over time as a result of modifications.
7. A parameter list has too many parameters:
Well-factored programs tend to have many small, well-defined routines that don’t need large
parameter lists. A long parameter list is a warning that the abstraction of the routine interface has
not been well thought out.
8. Changes within a class tend to be compartmentalized:
Sometimes a class has two or more distinct responsibilities. When that happens you find
yourself changing either one part of the class or another part of the class—but few changes
affect both parts of the class. That’s a sign that the class should be cleaved into multiple classes
along the lines of the separate responsibilities.
Reasons to refactoring:

9. A class doesn’t do very much:


Sometimes the need of refactoring code is that an old class doesn’t have much to do. If a class
doesn’t seem to be carrying its weight, ask if you should assign all of that class’s responsibilities
to other classes and eliminate the class altogether.
10. A middleman object isn’t doing anything:
If you find that most of the code in a class is just passing off calls to routines in other classes,
consider whether you should eliminate the middleman and call those other classes directly.
11. One class is overly intimate with another:
Encapsulation (information hiding) is probably the strongest tool you have to make your
program intellectually manageable and to minimize effects of code changes. Anytime you see
one class that knows more about another class than it should—including derived classes
knowing too much about their parents.
Reasons to refactoring:

12. A routine uses more features of another class than of its own class:
This suggests that the routine should be moved into the other class and then
invoked by its old class.
13. Data members are public:
Public data members are always a bad idea. They blur the line between interface
and implementation, and they inherently violate encapsulation and limit future
flexibility. Strongly consider hiding public data members behind access routines.
14. Comments are used to explain difficult code:
Comments have an important role to play, but they should not be used as a crutch
to explain bad code. “Don’t document bad code—rewrite it” .
Next member:

M. ABDULLAH
20011598-122
Specific Refactoring:

• Data-Level refactoring
• Statement Level refactoring
• Routine Level refactoring
• Class implementation refactoring
• Class interface refactoring
• System Level refactoring
Data Level Refactoring:

• Replace a magic number with a named constant (3.14)


• Rename a variable with a clearer or more informative name
• Move an expression inline (just return)
• Replace and expression with a routine
• Introduce an intermediate variable ( whose name summarizes
the expression)
• Convert a multiuse variable to multiple single-use variables
(i,j,temp)
Data Level Refactoring:

• Use a local variable for local purpose rather than a


parameter
• Convert a data primitive to a class (money,
temperature)
• Change an array to an object
• Encapsulate a collection (synchronization difficulties)
• Replace a traditional record with a data class
Statement Level Refactoring:

• Decompose a Boolean expression (well known


variables)
• Move a complex Boolean expression into a well
named Boolean function
• Consolidate fragments that are duplicated within
different parts of a conditional (Good bye!)
Statement Level Refactoring:

• Return as soon as you know the answer instead of


assigning a return value within nested if-then-else
statements
• Replace conditionals (especially repeated case
statements) with polymorphism
Routine Level Refactoring:

• Extract routine/extract method


• Move a routine’s code inline
• Convert a long routine to a class
• Substitute a simple algorithm for a complex algorithm
• Add a parameter
• Remove a parameter
• Separate query operations from modification operations
(getTotal())
Routine Level Refactoring:

• Combine similar routines by parameterizing them


• Separate routines whose behaviour depends on
parameters passed in
• Pass a whole object rather than specific fields
• Pass specific fields rather than a whole object
• Encapsulate downcasting (return most specific type
of object ie child class’s object)
Class Implementation Refactoring:

• Change value objects to reference objects (large


complex object- master copy)
• Change reference objects to value objects
• Extract specialized code into a subclass
• Combine similar code into a superclass
Class Interface Refactoring:

• Move a routine to another class


• Convert one class to two
• Eliminate a class
• Hide a delegate (class A calls class B and class C)
• Remove a middleman (class A should call class C)
Class Interface Refactoring:

• Introduce a foreign routine


• Introduce an extension class
• Encapsulate an exposed member variable (use
getters)
• Remove Set() routines for fields that cannot be
changed (initialized at creation & unchanged)
Class Interface Refactoring:

• Hide routines that are not intended to be used


outside the class
• Encapsulate unused routines
• Collapse a superclass and subclass if their
implementations are very similar
System Level Refactoring:

• Create a definitive reference source for data you can’t control


• Change unidirectional class association to bidirectional class
association (both classes should know about each other)
• Change bidirectional class association to unidirectional class
association
• Provide a factory method rather than a simple constructor
• Replace error codes with exceptions or vice versa (make sure
the code is using the standard approach)
Next member:

AYEZA HASSAN
20011598-112
Refactoring safety:

Refactoring is a powerful technique for improving code quality. Like all powerful
tools, refactoring can cause more harm than good if misused. A few simple
guidelines can prevent refactoring missteps.
1. Save the code you start with :
Before you begin refactoring, make sure you can get back to the code you started
with. Save a version in your revision control system, or copy the correct files to a
backup directory.
2. Keep refactoring small :
Some refactoring are larger than others, and exactly what constitutes “one
refactoring” can be a little fuzzy. Keep the refactoring small so that you fully
understand all the impacts of the changes you make.
Refactoring safety:

3. Do Refactoring one at a time :


Some refactorings are more complicated than others. For all but the simplest refactorings,
do the refactorings one at a time, recompiling and retesting after a refactoring before doing
the next one.
4. Make a list of steps you intend to take :
A natural extension of the Pseudocode Programming Process is to make a list of the
refactorings that will get you from Point A to Point B. Making a list helps you keep each
change in context.
5. Use your compiler warnings :
It’s easy to make small errors that slip past the compiler. Setting your compiler to the
pickiest warning level possible will help catch many errors almost as soon as you type
them.
Refactoring safety:

6. Make a parking lot:


When you’re midway through one refactoring, you’ll sometimes find that you need another
refactoring. Midway through that refactoring, you find a third refactoring that would be
beneficial. For changes that aren’t needed immediately, make a “parking lot,” a list of the
changes that you’d like to make at some point but that don’t need to be made right now.
7. Make frequent checkpoints :
It’s easy to find the code suddenly going sideways while you’re refactoring. In addition to
saving the code you started with, save checkpoints at various steps in a refactoring session so
that you can get back to a working program if you code yourself into a dead end.
8. Retest :
Reviews of changed code should be complemented by retests. Of course, this is dependent on
having a good set of test cases in the first place
Refactoring safety:

9. Review the changes:


If reviews are important the first time
through, they are even more important
during subsequent modifications. Ed
Yourdon reports that programmers typically
have more than a 50 percent chance of
making an error on their first attempt to
make a change .Interestingly, if programmers
work with a substantial portion of the code,
rather than just a few lines, the chance of
making a correct modification improves,
Specifically, as the number of lines changed
increases from one to five lines, the chance
of making a bad change increases. After that,
the chance of making a bad change
decreases.
Refactoring stratigies:

Consider the following guidelines when deciding which refactorings are


most important:
1. Refactor when you add a routine
When you add a routine, check whether related routines are well organized.
If not, refactor them
2. Refactor when you fix a defect
Use the understanding you gain from fixing a bug to improve other code
that might be prone to similar defects
Refactoring stratigies:

3. In a maintenance environment, improve the parts you touch


Code that is never modified doesn’t need to be refactored. But when you do
touch a section of code, be sure you leave it better than you found it
4. Target high-complexity modules
Another approach is to focus on modules that have the highest complexity
ratings. One classic study found that program quality improved
dramatically when maintenance programmers focused their improvement
efforts on the modules that had the highest complexity .
Refactoring stratigies:

5. Target error-prone modules


Some modules are more error-prone and brittle than others. Is there a
section of code that you and everyone else on your team is afraid of?
That’s probably an error-prone module. Although most people’s natural
tendency is to avoid these challenging sections of code, targeting these
sections for refactoring can be one of the more effective strategies.
Refactoring stratigies:

6. Define an interface between clean code and ugly code, and then move code
across the interface
The “real world” is often messier than you’d like. The messiness might
come from complicated business rules, hardware interfaces, or software
interfaces. A common problem with geriatric systems is poorly written
production code that must remain operational at all times.
An effective strategy for rejuvenating geriatric production systems is to
designate some code as being in the messy real world, some code as
being in an idealized new world, and some code as being the interface
between the two.
Refactoring strategies:
THE END

You might also like