Refactoring Improving code after it has been written.

Slides:



Advertisements
Similar presentations
Continuation of chapter 6…. Nested while loop A while loop used within another while loop is called nested while loop. Q. An illustration to generate.
Advertisements

AP Computer Science Anthony Keen. Computer 101 What happens when you turn a computer on? –BIOS tries to start a system loader –A system loader tries to.
1 Classes and Objects in Java Parameter Passing, Delegation, Visibility Control, and Object Cleanup.
Programming with Java. Problem Solving The purpose of writing a program is to solve a problem The general steps in problem solving are: –Understand the.
Refactoring This lecture is divided into and introduction to refactoring and then several lessons. The intent is not to teach you all the refactorings.
Introduction to C# Erick Pranata © Sekolah Tinggi Teknik Surabaya 1.
Software Testing and Maintenance 1 Today’s Agenda  Course Evaluation  HW 4 Return  HW 5 Correction  Quiz 4 Next Class  Software Refactoring.
SwE 455 Program Slicing. Our Goals Debug your thousands lines of code easily by reducing the complexity of the program Write a robust program before testing.
START DEFINITIONS values (3) N1 = (8, 1,-9) i N1 average N3,2 sum N2 = 0 temp N1 Do not guess or assume any values! Follow the values of the variables.
Refactoring: Improving the Design of Existing Code © Martin Fowler, Martin Fowler.
Introduction to Application Programming IST 256 Application Programming for Information Systems Xiaozhong Liu
Refactoring Software Engineering Refactoring Software Engineering 2011 Department of Computer Science Ben-Gurion university Based on slides of: Mira Balaban.
1 CS100J 13 March 2006 Arrays. Reading: Secs 8.1, 8.2, 8.3. Listen to the following lectures on loops on your Plive CD. They are only 2-3 minutes long,
1 More on Inheritance Overview l Object: The father of all classes l Casting and Classes l Object Cloning l Importance of Cloning.
A Small Exercise Suppose you need to implement a movie rental system Your movie rental system must deal with Three kind of movie rental Three kind of movie.
Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler.
REFACTORING Improving the Design of Existing Code Atakan Şimşek e
26-Jun-15 Methods. About methods A method is a named group of declarations and statements If a method is in the same class, you execute those declarations.
Refactoring, continue. Announcements Due today Resubmit HW5 (feedback on HW5 in SVN) HW7 HW8 will be up tonight Due Saturday at 5:59! Quiz 9 Spring 15.
Test. A software house decides to develop a DVD renting program. The product manager identifies the following requirements: Every DVD will have a title,
Passing Other Objects Strings are called immutable which means that once a String object stores a value, it never changes –recall when we passed a message.
Chapter 7 Designing Classes. Class Design When we are developing a piece of software, we want to design the software We don’t want to just sit down and.
CS5103 Software Engineering Lecture 13 Software Refactoring Software Licenses.
Refactoring: Improving the Design of Existing Code © Martin Fowler, Martin Fowler.
Classes and Objects. Topics The Class Definition Declaring Instance Member Variables Writing Instance Member Methods Creating Objects Sending Messages.
The Java Programming Language
Passing Other Objects Strings are called immutable which means that once a String object stores a value, it never changes –recall when we passed a message.
What does a computer program look like: a general overview.
Refactoring An Automated Tool for the Tiger Language Leslie A Hensley
Control Structures Introduction Decision Statements The if Construct The if.. else Construct The switch Statement Iterative Constructs The while Construct.
Refactoring Software Engineering Refactoring Software Engineering 2012 Department of Computer Science Ben-Gurion university Based on slides of: Mira Balaban.
CS4723 Software Engineering Lecture 12 Software Design Quality.
Spring 2008 Mark Fontenot CSE 1341 Principles of Computer Science I Note Set 5.
Agile Software Development Lab Spring 2008 R O O T S 1 Sina Thomas ) XP: Extreme.
CSC1201: PROGRAMMING LANGUAGE 2 Aseel Al Hadlaq 2nd Term
CMP-MX21: Lecture 4 Selections Steve Hordley. Overview 1. The if-else selection in JAVA 2. More useful JAVA operators 4. Other selection constructs in.
Refactoring: Improving the Design of Existing Code © Martin Fowler, Martin Fowler.
Incremental Design Why incremental design? Goal of incremental design Tools for incremental design  UML diagrams  Design principles  Design patterns.
Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1.
Java Expressions MIS 3023 Business Programming Concepts II The University of Tulsa Professor: Akhilesh Bajaj All slides in this presentation ©Akhilesh.
Refactoring II Dealing with Polymorphism. Switch in Rental Switches on Movie! class Rental … public double getCharge() { double result = 0; switch (getMovie().getPriceCode()){
More loops while and do-while. Recall the for loop in general for (initialization; boolean_expression; update) { }
Design Patterns.
Software Construction and Evolution - CSSE 375 Making Method Calls Simpler Shawn and Steve Below – “Be the character!” The late acting teacher Lee Strasberg.
Refactoring. Announcements HW7 due today, HW8 coming up tomorrow (I’m taking a late day on posting HW8) Grades and feedback for HW0-5 in Homework Server.
Chapter 5 : Methods Part 2. Returning a Value from a Method  Data can be passed into a method by way of the parameter variables. Data may also be returned.
CSSE 375 Organizing Data – Part 1 Shawn and Steve Q1.
Refactoring. DCS – SWC 2 Refactoring ”A change made to the internal structure of software to make it easier to understand and cheaper to modify without.
COP 2220 Computer Science I Topics –Breaking Problems Down –Functions –User-defined Functions –Calling Functions –Variable Scope Lecture 4.
State ● What is state? ABCDE. State and Data Structures ABCDE A B C D E ● Data structures encode state. In doing so, they introduce state ● State of data.
第九讲 重构到模式. 什么是重构( Refactoring ) 所谓重构是这样一个过程:在不改变代码外在行为的 前提下,对代码做出修改,以改进程序的内部结构。
Java 5 Class Anatomy. User Defined Classes To this point we’ve been using classes that have been defined in the Java standard class library. Creating.
GetFamilyName( ) with one "name" field We will assume these specifications for the "name" field: The name field consists of these parts, in this order:
Abteilung für Telekooperation Video Shop Case Übung Softwareentwicklung 2 für Wirtschaftsinformatik Ismail Khalil Ibrahim Wieland Schwinger.
Refactoring (1). Software Evolution Cope with change Feature bloat Design decay Code duplications “Pattern time is refactoring time” Make future changes.
A (Very) Simple Example Consolidate duplicate conditional fragments if (isSpecialDeal()) { total = price * 0.95; send (); } else { total = price * 0.98;
Outline A. What is Refactoring? B. Why do we Refactor?
Method Mark and Lyubo.
Refactoring with inline temp, method, and class
Stack Memory 2 (also called Call Stack)
UML & Programming Martin Fowler.
Refactoring.
Reusability 11/29/2018© 2006 ITT Educational Services Inc.
private double amountFor(Rental aRental)
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
Exercise 11.1 Write a code fragment that performs the same function as the statement below without using the crash method Toolbox.crash(amount < 0,
Code Animation Examples
Take out a piece of paper and PEN.
Welcome back to Software Development!
Presentation transcript:

Refactoring Improving code after it has been written

The Problem: Design is not always optimal “Improving the design after it has been written” “Improving the design after it has been written” Code deteriorates over time with changes Code deteriorates over time with changes Make many small changes Make many small changes Test after each change Test after each change Radical change through cumulative effect Radical change through cumulative effect

An Example Write Software for Movie Rentals

The class Movie public class Movie{ public static final int CHILDRENS = 2; public static final int REGULAR = 0; public static final int NEW_RELEASE = 1; private String _title; private int _priceCode; public Movie(String title, int priceCode){ _title = title; _priceCode = priceCode;} public int getPriceCode(){return _priceCode;} public void setPriceCode(int arg){ _priceCode = arg;} public String getTitle(){return _title;} }

The class Rental public class Rental{ private Movie –movie; public Rental(Movie movie, int daysRented){ _movie = movie; _daysRented = daysRented;} public int getDaysRented(){return _daysRented;} public Movie getMovie(){return _movie;} }

The class Customer public class Customer{ private String _name; private Vector _rentals = new Vector(); public Customer (String name){_name = name;} public void addRental(Rental arg){ _rentals.addElement(arg);} public String getName(){return _name;} public void statement(); //see below }

Class Diagram of Rental Program Customer Rental Movie statement() int: daysRented int: priceCode 1 * 1 *

Sequence Diagram

Method statement (1 of 3) public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements()){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement();

Method statement (2 of 3) switch (each.getMovie().getPriceCode()){ case Movie.REGULAR: thisAmount += 2; if (each.getDaysRented()>2) thisAmount += (each.getDaysRented()-2)*1.5; break; case Movie.NEW_RELEASE: thisAmount += each.getDaysRented()*3; break; case Movie.CHILDRENS: thisAmount += 1.5; if (each.getDaysRented()>3) thisAmount += (each.getDaysRented()-3)*1.5; break; } //switch

Method statement (3 of 3) frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(thisAmount)+”\n”; totalAmount += thisAmount; result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; }

What is wrong? Program works Program works Method statement is way too long Method statement is way too long Decompose it into smaller pieces Decompose it into smaller pieces So find a logical piece of code So find a logical piece of code Try the switch statement Try the switch statement

Write method amountFor(Rental each); private int amountFor(Rental each){ int thisAmount = 0; switch (each.getMovie().getPriceCode()){ case Movie.REGULAR: thisAmount += 2; if (each.getDaysRented()>2) thisAmount += (each.getDaysRented()-2)*1.5; break; case Movie.NEWRELEASE: thisAmount += each.getDaysRented()*3; break; case Movie.CHILDRENS: thisAmount += 1.5; if (each.getDaysRented()-3)*1.5; break;} return thisamount; } //switch MoveMethod

public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements()){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement(); thisAmount = amountFor(each); frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(thisAmount)+”\n”; totalAmount += thisAmount; result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; }

Problem Tests reveal that return type is double, not int

Write it again private double amountFor(Rental aRental){ double result = 0; switch (aRental.getMovie().getPriceCode()){ case Movie.REGULAR: result += 2; if (aRental.getDaysRented()>2) result += (each.getDaysRented()-2)*1.5; break; case Movie.NEWRELEASE: result += aRental.getDaysRented()*3; break; case Movie.CHILDRENS: result += 1.5; if (aRental.getDaysRented()-3)*1.5; break; } return result; } //switch

Mistake was found Testing is crucial at each refactoring step

Examine new amountFor() It doesn’t use any customer data! It doesn’t use any customer data! Method is in the wrong place. Method is in the wrong place. Put it in rental Put it in rental It gets a new name: getCharge() It gets a new name: getCharge()

class Rental … public double getCharge() { double result = 0; switch (getMovie().getPriceCode()){ case Movie.REGULAR: result += 2; if (getDaysRented()>2) result += (getDaysRented()-2)*1.5; break; case Movie.NEWRELEASE: result += getDaysRented()*3; break; case Movie.CHILDRENS: result += 1.5; if (getDaysRented()-3)*1.5; break; } return result; } MoveMethod

class Customer… Private double amountFor(Rental aRental){ return aRental.getCharge(); }

Fix up program Have to find all references for amountFor and change to getCharge()

class customer… public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement(); thisAmount = amountFor(each); frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(thisAmount)+”\n”; totalAmount += thisAmount;} result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; }

becomes

class customer… public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement(); thisAmount = each.getCharge(); frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(thisAmount)+”\n”; totalAmount += thisAmount;} result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; }

Now notice thisAmount is redundant

class customer… public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement(); frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(each.getCharge())+”\n”; totalAmount += each.getCharge();} result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; } Replace Temp with Query

Now extract code for Frequent Renter Points

public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ Rental each = (Rental)rentals.nextElement(); frequentRenterPoints++; if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(each.getDaysRented()>1) frequentRenterPoints++; result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(each.getCharge())+”\n”; totalAmount += each.getCharge();} result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; } Extract Method

And put in in Rental:

class Customer… public String statement(){ double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ double thisAmount = 0; Rental each = (Rental)rentals.nextElement(); frequentRenterPoints += each.getFrequentRenterPoints(); result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(each.getCharge())+”\n”; totalAmount += each.getCharge();} result += “AmountOwed is “ + String.valueOf(totalAmount) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; }

class Rental… int getFrequentRenterPoints(){ if ((getMovie().getPriceCode() == Movie.NEW_RELEASE) &&(getDaysRented()>1) return 2; else return 1; }

RemoveTemp Variables Temps encourage complexity Temps encourage complexity Here: totalAmount and frequentRenterPoints Here: totalAmount and frequentRenterPoints Replace totalAmount with Customer method getTotalCharge() Replace totalAmount with Customer method getTotalCharge()

class Customer… public String statement(){ int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = “Rental Record for”+getname()+”\n”; while(rentals.hasMoreElements(){ Rental each = (Rental)rentals.nextElement(); frequentRenterPoints += each.getFrequentRenterPoints(); result += “\t”+each.getMovie().getTitle()+”\t”+ String.valueOf(each.getCharge())+”\n”; totalAmount += each.getCharge();} result += “AmountOwed is “ + String.valueOf(getTotalCharge()) +”\n”; result += “You earned “ + String.valueOf( frequentRenterPoints)+”frequent renter points”; return result; } Replace Temp with Query

class customer… private double getTotalCharge(){ double result = 0; Enumeration rentals = _rentals.elements(); while (rentals.hasMoreElements()){ Rental each = (Rental)rentals.nextElement(); result += each.getCharge(); } return result; }

Now do the same for frequentRenterPoints