Download - Vukoje.NET - Refactoring
-
8/14/2019 Vukoje.NET - Refactoring
1/35
Refactoring and Coding
StandardMilan Vukoje
http://www.vukoje.net/http://www.vukoje.net/ -
8/14/2019 Vukoje.NET - Refactoring
2/35
Themes
Is code important?
Code Refactoring
Coding Standard
Code Review
Tools
-
8/14/2019 Vukoje.NET - Refactoring
3/35
Importance of code
Is construction relatively mechanical
process?
Only activity thats guaranteed to be done 50-65% of overall effort
50-75% of overall errors
managing software complexity
-
8/14/2019 Vukoje.NET - Refactoring
4/35
Technical Debt
Ward Cunningham
When software organization chooses a
design or construction approach that'sexpedient in the short term but that
increases complexity and is more costly in
the long term.
Unintentional and intentional debt
Scrum - make up issues
-
8/14/2019 Vukoje.NET - Refactoring
5/35
Coding Horror
Fear Stress
Cargo cult programming/Just in case coding
Heisenbug - bug that disappears or alters itscharacteristics when an attempt is made to study
it.
Mandelbug - bug whose causes are so complex
that its behavior appears chaotic. Schroedinbug - bug that manifests only after
someone reading source code or using the
program in an unusual way notices that it never
should have worked in the first place.
-
8/14/2019 Vukoje.NET - Refactoring
6/35
Refactoring
Refactoring(noun): a change made to the internal structure ofsoftware to make it easier to understand and cheaper to modifywithout changing its observable behavior.
Refactor(verb): to restructure software by applying a series of
refactorings without changing its observable behavior. Set of rules and techniques for simplifying process and reducing
chances for error
-
8/14/2019 Vukoje.NET - Refactoring
7/35
The Book
Refactoring: Improving the Design of Existing
Code --Martin Fowler
-
8/14/2019 Vukoje.NET - Refactoring
8/35
Need for refactoring
Micro design Code evolution
Embracing change Clear API with expected behavior Avoiding coding horror Why change something that works?
We want programs that are easy to read, that haveall logic specified in one and only one place, thatdo not allow changes to endanger existingbehavior, and that allow conditional logic to beexpressed as simply as possible. Kent Beck
-
8/14/2019 Vukoje.NET - Refactoring
9/35
Agile methodologies and
Refactoring
XP no upfront design
TDD red, green, refactorScrum make up user stories, educating
management about refactoring
-
8/14/2019 Vukoje.NET - Refactoring
10/35
Code smells [1]
Duplicated Code
Long Method
Large Class Long Parameter List
Feature Envy
Data Clumps Primitive Obsession
-
8/14/2019 Vukoje.NET - Refactoring
11/35
Code smells[2]
Switch Statements
Lazy Class
Speculative Generality
Temporary Field
Message Chains
Middle Man
Data Class Refused Bequest
Shotgun Surgery
-
8/14/2019 Vukoje.NET - Refactoring
12/35
Refactorings: Composing
Methods
Extract Method
Inline Method
Inline Temp
Replace Temp with Query
Introduce Explaining Variable
Split Temporary Variable
Remove Assignments to Parameters Replace Method with Method Object
Substitute Algorithm
-
8/14/2019 Vukoje.NET - Refactoring
13/35
Extract Method
You have a code fragment that can be grouped together. Turn the fragment into a method whose name explains the purpose of the method.
void printOwing(double amount) {
printBanner();
//print details
System.out.println ("name:" + _name);System.out.println ("amount" + amount);
}
void printOwing(double amount) {
printBanner();printDetails(amount);
}
void printDetails (double amount) {
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}
-
8/14/2019 Vukoje.NET - Refactoring
14/35
Inline Method
A method's body is just as clear as its name. Put the method's body into the body of its callers and remove the method.
int getRating() {
return (moreThanFiveLateDeliveries()) ? 2 : 1;
}boolean moreThanFiveLateDeliveries() {
return _numberOfLateDeliveries > 5;
}
int getRating() {
return (_numberOfLateDeliveries > 5) ? 2 : 1;
}
-
8/14/2019 Vukoje.NET - Refactoring
15/35
-
8/14/2019 Vukoje.NET - Refactoring
16/35
Replace Temp with Query
You are using a temporary variable to hold the result of an expression. Extract the expression into a method. Replace all references to the temp with the
expression. The new method can then be used in other methods.
double basePrice = _quantity * _itemPrice;
if (basePrice > 1000)
return basePrice * 0.95;else
return basePrice * 0.98;
if (basePrice() > 1000)
return basePrice() * 0.95;else
return basePrice() * 0.98;
...
double basePrice() {
return _quantity * _itemPrice;
}
-
8/14/2019 Vukoje.NET - Refactoring
17/35
Temp variable problem
The problem with temps is that they are
temporary and local. Because they can be seen
only in the context of the method in which theyare used, temps tend to encourage longer
methods, because that's the only way you can
reach the temp. By replacing the temp with a
query method, any method in the class can get atthe information. That helps a lot in coming up
with cleaner code for the class.
-
8/14/2019 Vukoje.NET - Refactoring
18/35
Introduce Explaining Variable
You have a complicated expression. Put the result of the expression, or parts of the expression, in a temporary variable with a name
that explains the purpose.
if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0 )
{// do something
}
final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1;final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// do something
}
-
8/14/2019 Vukoje.NET - Refactoring
19/35
Split Temporary Variable
You have a temporary variable assigned to more than once, but is not a loopvariable nor a collecting temporary variable.
Make a separate temporary variable for each assignment.
double temp = 2 * (_height + _width);
System.out.println (temp);
temp = _height * _width;
System.out.println (temp);
final double perimeter = 2 * (_height + _width);
System.out.println (perimeter);
final double area = _height * _width;
System.out.println (area);
-
8/14/2019 Vukoje.NET - Refactoring
20/35
Remove Assignments to
Parameters
The code assigns to a parameter. Use a temporary variable instead.
int discount (int inputVal, int quantity, int yearToDate) {
if (inputVal > 50) inputVal -= 2;
int discount (int inputVal, int quantity, int yearToDate) {
int result = inputVal;
if (inputVal > 50) result -= 2;
Enforces clarity between pass by value and pass by reference parameters.
-
8/14/2019 Vukoje.NET - Refactoring
21/35
Replace Method with Method
Object
You have a long method that uses local variables in such a way that
you cannot apply Extract Method.
Turn the method into its own object so that all the local variables
become fields on that object. You can then decompose the method
into other methods on the same object.
Substitute Algorithm
You want to replace an algorithm with one that is clearer.
Replace the body of the method with the new algorithm.
-
8/14/2019 Vukoje.NET - Refactoring
22/35
Refactorings: Simplifying
Conditional Expressions
Decompose Conditional
Consolidate Conditional Expression
Consolidate Duplicate Conditional Fragments
Remove Control Flag
Replace Nested Conditional with Guard Clauses
Replace Conditional with Polymorphism
Introduce Null Object Introduce Assertion
-
8/14/2019 Vukoje.NET - Refactoring
23/35
Decompose Conditional
You have a complicated conditional (if-then-else) statement. Extract methods from the condition, then part, and else parts.
if (date.before (SUMMER_START) || date.after(SUMMER_END))
charge = quantity * _winterRate + _winterServiceCharge;else charge = quantity * _summerRate;
if (notSummer(date))charge = winterCharge(quantity);
else charge = summerCharge (quantity);
-
8/14/2019 Vukoje.NET - Refactoring
24/35
Consolidate Conditional
Expression
You have a sequence of conditional tests with the same result. Combine them into a single conditional expression and extract it.
double disabilityAmount() {
if (_seniority < 2) return 0;if (_monthsDisabled > 12) return 0;
if (_isPartTime) return 0;
// compute the disability amount
double disabilityAmount() {
if (isNotEligableForDisability()) return 0;
// compute the disability amount
-
8/14/2019 Vukoje.NET - Refactoring
25/35
Consolidate Duplicate
Conditional Fragments
The same fragment of code is in all branches of a conditional expression. Move it outside of the expression.
if (isSpecialDeal()) {
total = price * 0.95;
send();
}else {
total = price * 0.98;
send();
}
if (isSpecialDeal())total = price * 0.95;
else
total = price * 0.98;
send();
-
8/14/2019 Vukoje.NET - Refactoring
26/35
Refactorings: Making Method
Calls Simpler
Rename Method
Separate Query from Modifier
Parameterize Method
Preserve Whole Object
Hide Method
Replace Error Code with Exception Replace Exception with Test
-
8/14/2019 Vukoje.NET - Refactoring
27/35
Refactorings: Moving Features
between objects
Move Method
Move Field
Extract Class
Inline Class
Hide Delegate
Remove Middle Man
-
8/14/2019 Vukoje.NET - Refactoring
28/35
Refactorings: Dealing with
Generalization
Pull Up Field Pull Up Method Push Down Method
Push Down Field Extract Subclass Extract Superclass Extract Interface
Collapse Hierarchy Replace Inheritance with Delegation Replace Delegation with Inheritance
-
8/14/2019 Vukoje.NET - Refactoring
29/35
Refactoring: Organizing Data
Encapsulate Field
Replace Data Value with Object
Replace Magic Number with SymbolicConstant
Encapsulate Collection
Replace Type Code with SubclassesReplace Type Code with State/Strategy
Replace Subclass with Fields
-
8/14/2019 Vukoje.NET - Refactoring
30/35
Refactoring and Software
Design
Design for today vs. Design for tomorrow Upfront design Do a minimum that works
Refactoring to patterns vs.Patternitis/Overengineering Cohesion and Coupling Eliminate duplicate code Without refactoring, the design of the program will
decay XP no upfront design Flexible vs. simple design
-
8/14/2019 Vukoje.NET - Refactoring
31/35
Code Readability
Makes software easier to understand, leading to
faster modifications and faster adding of new
features
Optimizing code for human rather than computers Reducing the amount of code
Make the code better communicate its purpose
Code like lazy programmer
Use refactoring to help understand unfamiliar code
-
8/14/2019 Vukoje.NET - Refactoring
32/35
When Should You Refactor?
Refactoring is something you do all the time in littlebursts.
Refactor when you add function Refactor when you need to fix a bug Refactor as you do a code review If you can get today's work done today, but you do it
in such a way that you can't possibly get tomorrow'swork done tomorrow, then you lose. Kent Beck
Refactoring and Unit Tests?
-
8/14/2019 Vukoje.NET - Refactoring
33/35
What Do I Tell My Manager?
If the manager is quality oriented, then the thing to
stress is the quality aspects. Tons of studies show that technical reviews are an
important way to reduce bugs and thus speed up
development.
Don't tell!?
-
8/14/2019 Vukoje.NET - Refactoring
34/35
When you shouldnt refactor?
Databases data migration, reused structuresacross applications
Changing published interfaces Rewriting from scratch instead Code is so full of bugs that you cannot stabilize it Code has to work mostly correctly before you
refactor. When you are very close to a deadline Not having enough time usually is a sign that you
need to do some refactoring. Dont overdo it.
-
8/14/2019 Vukoje.NET - Refactoring
35/35
Performance and Refactoring
Refactoring certainly will make software go
more slowly, but it also makes the software
more amenable to performance tuning.
Changes that improve performance usually
make the program harder to work with.
If you optimize all the code equally, you end
up with 90 percent of the optimizationswasted, because you are optimizing code
that isn't run much.