Refactoring and Coding Standard: Milan Vukoje

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 35

Refactoring and Coding

Standard
Milan Vukoje
www.vukoje.net
[email protected]
Themes

 Iscode important?
 Code Refactoring

 Coding Standard

 Code Review

 Tools
Importance of code

 Isconstruction relatively mechanical


process?
 Only activity that’s guaranteed to be done

 50-65% of overall effort

 50-75% of overall errors

 managing software complexity


Technical Debt

 Ward Cunningham
 When software organization chooses a
design or construction approach that's
expedient in the short term but that
increases complexity and is more costly in
the long term.
 Unintentional and intentional debt

 Scrum - make up issues


Coding Horror
 Fear
 Stress
 Cargo cult programming/Just in case coding
 Heisenbug - bug that disappears or alters its
characteristics 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.
Refactoring
 Refactoring (noun): a change made to the internal structure of
software to make it easier to understand and cheaper to modify
without 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
The Book

 Refactoring:Improving the Design of Existing


Code --Martin Fowler
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 have
all logic specified in one and only one place, that
do not allow changes to endanger existing
behavior, and that allow conditional logic to be
expressed as simply as possible. Kent Beck
Agile methodologies and
Refactoring

 XP – no upfront design
 TDD – red, green, refactor

 Scrum – make up user stories, educating


management about refactoring
Code smells [1]

 Duplicated Code
 Long Method
 Large Class
 Long Parameter List
 Feature Envy
 Data Clumps
 Primitive Obsession
Code smells[2]

 Switch Statements
 Lazy Class
 Speculative Generality
 Temporary Field
 Message Chains
 Middle Man
 Data Class
 Refused Bequest
 Shotgun Surgery
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
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);
}
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;
}
Inline Temp
 You have a temp that is assigned to once with a simple expression, and the
temp is getting in the way of other refactorings.
 Replace all references to that temp with the expression.

double basePrice = anOrder.basePrice();


return (basePrice > 1000)

return (anOrder.basePrice() > 1000)


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;
}
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 they
are 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 at
the information. That helps a lot in coming up
with cleaner code for the class.
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
}
Split Temporary Variable
 You have a temporary variable assigned to more than once, but is not a loop
variable 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);
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.


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.
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
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);
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
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();
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
Refactorings: Moving Features
between objects

 Move Method
 Move Field

 Extract Class

 Inline Class

 Hide Delegate

 Remove Middle Man


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
Refactoring: Organizing Data

 Encapsulate Field
 Replace Data Value with Object

 Replace Magic Number with Symbolic


Constant
 Encapsulate Collection

 Replace Type Code with Subclasses

 Replace Type Code with State/Strategy

 Replace Subclass with Fields


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
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
When Should You Refactor?

 Refactoring is something you do all the time in little


bursts.
 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's
work done tomorrow, then you lose. – Kent Beck
 Refactoring and Unit Tests?
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!?
When you shouldn’t refactor?

 Databases – data migration, reused structures


across 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.
 Don’t overdo it.
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 optimizations
wasted, because you are optimizing code
that isn't run much.

You might also like