vukoje.net - refactoring

Upload: vukojekg

Post on 30-May-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/14/2019 Vukoje.NET - Refactoring

    1/35

    Refactoring and Coding

    StandardMilan Vukoje

    [email protected]

    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.