This site is from a past semester! The current version will be here when the new semester starts.
CS2113/T 2021 Jan-May
  • Full Timeline
  • Week 1 [Mon, Jan 11th]
  • Week 2 [Mon, Jun 21st]
  • Week 3 [Mon, Jun 28th]
  • Week 4 [Mon, Jul 5th]
  • Week 5 [Mon, Jul 12th]
  • Week 6 [Mon, Jul 19th]
  • Week 7 [Mon, Jul 26th]
  • Week 8 [Mon, Aug 9th]
  • Week 9 [Mon, Aug 16th]
  • Week 10 [Mon, Aug 23rd]
  • Week 11 [Mon, Aug 30th]
  • Week 12 [Mon, Sep 6th]
  • Week 13 [Mon, Sep 13th]
  • Textbook
  • Admin Info
  • Dashboards
  •  Individual Project (iP):
  • Individual Project Info
  • iP Upstream Repo
  • iP Code Dashboard
  • iP Progress Dashboard

  •  Team Project (tP):
  • Team Project Info
  • Reference AB3
  • Team List
  • tP Code Dashboard
  • tP Progress Dashboard
  • Java exercises
  • Report Bugs
  • Forum
  • Gitter (Chat)
  • Instructors
  • Announcements
  • Files (handouts, submissions etc.)
  • Tutorial Schedule
  • Java Coding Standard
  • Git Conventions
  • Forum Activities Dashboard
  • Participation Dashboard
  • Refactoring

    Can explain refactoring

    The first version of the code you write may not be of production quality. It is OK to first concentrate on making the code work, rather than worry over the quality of the code, as long as you improve the quality later. This process of improving a program's internal structure in small steps without modifying its external behavior is called refactoring.

    • Refactoring is not rewriting: Discarding poorly-written code entirely and re-writing it from scratch is not refactoring because refactoring needs to be done in small steps.
    • Refactoring is not bug fixing: By definition, refactoring is different from bug fixing or any other modifications that alter the external behavior (e.g. adding a feature) of the component in concern.

    Improving code structure can have many secondary benefits: e.g.

    • hidden bugs become easier to spot
    • improve performance (sometimes, simpler code runs faster than complex code because simpler code is easier for the compiler to optimize).

    Given below are two common refactorings (more).

    Refactoring Name: Consolidate Duplicate Conditional Fragments

    Situation: The same fragment of code is in all branches of a conditional expression.

    Method: Move it outside of the expression.

    Example:

    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();
    
    
    if is_special_deal:
        total = price * 0.95
        send()
    else:
        total = price * 0.98
        send()
    
     → 
    if is_special_deal:
        total = price * 0.95
    else:
        total = price * 0.98
        
    send()
    

    Refactoring Name: Extract Method

    Situation: You have a code fragment that can be grouped together.

    Method: Turn the fragment into a method whose name explains the purpose of the method.

    Example:

    void printOwing() {
        printBanner();
    
        // print details
        System.out.println("name:	" + name);
        System.out.println("amount	" + getOutstanding());
    }
    

    void printOwing() {
        printBanner();
        printDetails(getOutstanding());
    }
    
    void printDetails(double outstanding) {
        System.out.println("name:	" + name);
        System.out.println("amount	" + outstanding);
    }
    
    def print_owing():
        print_banner()
    
        # print details
        print("name:	" + name)
        print("amount	" + get_outstanding())
    

    def print_owing():
        print_banner()
        print_details(get_outstanding())
    
    def print_details(amount):
        print("name:	" + name)
        print("amount	" + amount)
    

    Some IDEs have builtin support for basic refactorings such as automatically renaming a variable/method/class in all places it has been used.

    Refactoring, even if done with the aid of an IDE, may still result in regressions. Therefore, each small refactoring should be followed by regression testing.

    Choose the correct statements.

    • a. Refactoring can improve understandability
    • b. Refactoring can uncover bugs
    • c. Refactoring can result in better performance
    • d. Refactoring can change the number of methods/classes

    a, b, c, d

    Explanation:

    • (a, b, c) Although the primary aim of refactoring is to improve the internal code structure, there are other secondary benefits.
    • (d) Some refactorings result in adding/removing methods/classes.

    Do you agree with the following statement? Justify your answer.

    Statement: Whenever you refactor code to fix bugs, you need not do regression testing if the bug fix was minor.

    There are two flaws in the given statement.

    DISAGREE.

    1. Even a minor change can have major repercussions on the system. You MUST do regression testing after each change, no matter how minor it is.
    2. Fixing bugs is technically not refactoring.

    Explain what refactoring is and why it is not the same as rewriting, bug fixing, or adding features.

    Can apply some basic refactoring

    Given below are some more commonly used refactorings. A more comprehensive list is available at refactoring-catalog.

    1. Consolidate Conditional Expression
    2. Decompose Conditional
    3. Inline Method
    4. Remove Double Negative
    5. Replace Magic Literal
    6. Replace Nested Conditional with Guard Clauses
    7. Replace Parameter with Explicit Methods
    8. Reverse Conditional
    9. Split Loop
    10. Split Temporary Variable
    Can decide when to apply a given refactoring

    You know that it is important to refactor frequently so as to avoid the accumulation of ‘messy’ code which might get out of control. But how much refactoring is too much refactoring? It is too much refactoring when the benefits no longer justify the cost. The costs and the benefits depend on the context. That is why some refactorings are ‘opposites’ of each other (e.g. extract method vs inline method).

    ‘Extract method’ and ‘Inline method’ refactorings

    a