Software Construction and Evolution - CSSE 375 Composing Methods

Slides:



Advertisements
Similar presentations
12-Dec-14 Refactoring IV. Previously discussed bad smells Duplicated code — and other forms of redundancy Long method — use short methods that delegate.
Advertisements

About Me – Frank Xu Education ▫ North Dakota State University  Ph.D. in Software Engineering ▫ Towson University  MS in Computer Science ▫ Southeast.
© 2010 Shawn A. Bohner Software Construction and Evolution - CSSE 375 Even more Bad Smells in Code Shawn & Steve Q1 Shawn & Steve Hint 
1 Software Maintenance and Evolution CSSE 575: Session 2, Part 2 Composing Methods Steve Chenoweth Office Phone: (812) Cell: (937)
Refactoring: Improving the Design of Existing Code © Martin Fowler, Martin Fowler.
Software Construction and Evolution - CSSE 375 Bad Smells in Code Shawn Bohner & Steve Chenoweth.
Software Engineering Key Refactorings
1 Software Maintenance and Evolution CSSE 575: Session 2, Part 3 Moving Features Between Objects Steve Chenoweth Office Phone: (812) Cell: (937)
1 Software Maintenance and Evolution CSSE 575: Session 1, Part 4 Even more Bad Smells in Code Steve Chenoweth Office Phone: (812) Cell: (937)
Introduction to Refactoring Excerpted from ‘What is Refactoring?’ by William C. Wake and Refactoring: Improving the Design of Existing Code by Martin Fowler.
George Blank University Lecturer. REFACTORING Improving the Design of Existing Code Supplement to Ian Sommerville, Software Engineering, Chapter 20 Prepared.
25-Jun-15 Refactoring III. General philosophy A refactoring is just a way of rearranging code Refactorings are used to solve problems If there’s no problem,
REFACTORING Improving the Design of Existing Code Atakan Şimşek e
Refactoring – III Measured Smells. Smells Covered 1. Comments 2. Long method 3. Large Class 462.
1 Software Maintenance and Evolution CSSE 575: Session 1, Part 3 Bad Smells in Code - 1 Steve Chenoweth Office Phone: (812) Cell: (937)
Refactoring. Mathematics: Factor ● fac·tor – One of two or more quantities that divides a given quantity without a remainder, e.g., 2 and 3 are factors.
Refactoring - A disciplined approach to rework for better design.
Refactoring Improving the structure of existing code Refactoring1.
Chapter 7: Bad Code Smells Omar Meqdadi SE 3860 Lecture 7 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
Small changes to code to improve it. Refactoring Defined A change made to the internal structure of software to make it easier to understand and cheaper.
Refactoring (continued) Source: "Refactoring: Improving the Design of Existing Code", Martin Fowler.
SWE 316: Software Design and Architecture Objectives Lecture # 20 Improving the existing design: Refactoring SWE 316: Software Design and Architecture.
Improving the Quality of Existing Code Svetlin Nakov Telerik Corporation
1 Software Maintenance and Evolution CSSE 575: Session 3, Part 1 Simplifying Conditionals Steve Chenoweth Office Phone: (812) Cell: (937)
Refactoring1 Improving the structure of existing code.
Introduction to Refactoring Jim Cooper Falafel Software.
Informatics 122 Software Design II
Incremental Design Why incremental design? Goal of incremental design Tools for incremental design  UML diagrams  Design principles  Design patterns.
Software Engineering CS3003 Lecture 4 Code bad smells and refactoring.
Refactoring: Code Smells. Admin Notes REGISTER FOR BLACKBOARD Watch blackboard site for updates on class as hurricane season approaches.
Refactoring. Refactoring Overview  What is refactoring?  What are four good reasons to refactor?  When should you refactor?  What is a bad smell (relative.
Refactoring 2. Admin Blackboard Quiz Acknowledgements Material in this presentation was drawn from Martin Fowler, Refactoring: Improving the Design of.
REFACTORINGREFACTORING. Realities Code evolves substantially during development Requirements changes 1%-4% per month on a project Current methodologies.
NJIT 1 Test Driven Development and Refactoring Larman, Chapter 21.
Refactoring II Dealing with Polymorphism. Switch in Rental Switches on Movie! class Rental … public double getCharge() { double result = 0; switch (getMovie().getPriceCode()){
Module 3. Smells Between Classes Course: Refactoring.
1 Software Maintenance and Evolution CSSE 575: Session 2, Part 1 Refactoring Principles Steve Chenoweth Office Phone: (812) Cell: (937)
Software Construction and Evolution - CSSE 375 Making Method Calls Simpler Shawn and Steve Below – “Be the character!” The late acting teacher Lee Strasberg.
1 Software Maintenance and Evolution CSSE 575: Session 3, Part 3 Dealing with Generalization Steve Chenoweth Office Phone: (812) Cell: (937)
Refactoring Advanced Software Engineering Dr Nuha El-Khalili.
Refactoring. Mathematics: Factor ● fac·tor – One of two or more quantities that divides a given quantity without a remainder, e.g., 2 and 3 are factors.
Refactoring1 Improving the structure of existing code.
Pertemuan 12 Refactoring Mata kuliah: T0144 – Advanced Topics in Software Engineering Tahun: 2010.
Software Construction and Evolution - CSSE 375 Simplifying Conditionals Shawn & Steve.
Refactoring Constants and Variables Lesson Three: Constants and Variables.
CSSE 375 Organizing Data – Part 1 Shawn and Steve Q1.
Software Construction and Evolution - CSSE 375 Dealing with Generalization Steve and Shawn Left – In the 1990 movie “The Freshman,” Matthew Broderick,
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.
Code Refactoring Milan Vukoje Soprex SkfOffice2 SkfOffice3 Big5 Quality oriented We are hiring…
Catalog of Refactoring (1) Composing Methods. Code Smells Long methods Dubious temporary variables Dubious methods.
ICONFINDER ICONFINDER Founded Django based web application -PostgreSQL -Elasticsearch -Amazon Elastic Compute.
Catalog of Refactoring (6) Making Method Calls Simpler.
A (Very) Simple Example Consolidate duplicate conditional fragments if (isSpecialDeal()) { total = price * 0.95; send (); } else { total = price * 0.98;
Principles and examples
Steve Chenoweth Office Phone: (812) Cell: (937)
Steve Chenoweth Office Phone: (812) Cell: (937)
Steve Chenoweth Office Phone: (812) Cell: (937)
Refactoring and Code Smells
Refactoring with inline temp, method, and class
بازآرایی برنامه Code Refactoring
Refactoring III 27-Nov-18.
Code Smells 1.
Improving the structure of existing code
Refactoring and Code Smells
Refactoring III 25-Dec-18.
Refactoring.
Refactoring and Code Smells
Refactoring.
Refactoring and Code Smells
Presentation transcript:

Software Construction and Evolution - CSSE 375 Composing Methods Q1: Why does a large part of refactoring involve Composing Methods ?   The code’s appearance should remind you of a symphony! Image from http://cellobello.com/blog/index.php/composing-and-playing-music-how-composing-helps-your-playing/ Shawn & Steve Ch 6 in Fowler Q1 

Composing Methods What they do! How quickly understood? Refactoring deals a lot with composing methods to properly package code Refactor methods that are too long or do too much Extract Method Split Temporary Variable Inline Method Remove Assignments to Parameters Inline Temp Replace Temp with Query Replace Method with Method Object Introduce Explaining Variables Substitute Algorithm A lot of method’s information gets buried by their complex logic Q2: What does the Composing Methods refactoring category address in general? Q2 Read about these on your own! 

Extract Method Situation: You have a code fragment that can be grouped together Method is too long Needs Clarity – comments to reflect purpose Undue redundancy Solution: Turn fragment into a method whose name explains the purpose of the method Shorter well-named methods Can be used by other methods Higher-level methods read more like a series of comments 

Exact Method: Simple Example void printOwing() { printBanner(); //print details System.out.println("name: " + _name); System.out.println("amount: " + amount); } Clue bird landing What is wrong with this code fragment? 

Extract Method: Simple Example void printOwing() { printBanner(); printDetails(amount); } void printDetails (double amount) { System.out.println ("name: " + _name); System.out.println ("amount " + amount);

Mechanics Create a new method and name it after “what it does” – it’s intention Copy extracted code from source into target Scan extracted method for references to any variables that are local to the source method Local variables /parameters to the target method Check for temporary variables used within extracted code If present, declare them in the target method as temporary variables Temporary variables that are read from the extracted code (used elsewhere) are passed into the target method as parameters Q3: After extracting a method, what key thing should you remember to do? Q3 

Mechanics (continued) Check for local-scope variables modified by extracted code 1 modified variable: treat extracted code as query and assign result to variable concerned More than 1 variable: can’t extract method From extracted code, pass local-scope variables into target as parameters Replace extracted code in source method with a call to target method Compile and test Q3 

More Detailed Example Problem 1 Problem 2 Problem 3  void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; // print banner System.out.println ("**************************"); System.out.println ("***** Customer Owes ******"); // calculate outstanding while (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } //print details System.out.println ("name:" + _name); System.out.println ("amount" + outstanding); Problem 1 Problem 2 So, what is wrong with this code fragment? [[comments and long method]] Problem 3 

More Detailed Example – Extract 2 Methods void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); } void printBanner() { // print banner System.out.println ("**************************"); System.out.println ("***** Customer Owes ******"); Extract 2 Extract 3 Note the local variable “outstanding”…

More Detailed Example – Extract Orders void printOwing() { double outstanding = getOutstanding(); printBanner(); PrintDetails(outstanding); } double getOutstanding() { Enumeration e = _orders.elements(); double outstanding = 0.0; while (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); return outstanding; void printDetails (double outstanding) { … void printBanner() {… Extract 1 Note “Enumberation e” and” double outstanding” variables go local Enumeration is used only in extracted code, so we moved it entirely within the new method

More Detailed Example – Extracted Methods void printOwing() { double outstanding = getOutstanding(); printBanner(); PrintDetails(outstanding); } double getOutstanding() { Enumeration e = _orders.elements(); double outstanding = 0.0; while (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount();} return outstanding; void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); void printBanner() { System.out.println ("**************************"); System.out.println ("***** Customer Owes ******"); Extract 1 Extract 2 Not Done yet… Q4: The methods have been extracted… So, what is still wrong with this code fragment? [[Local variables need to be resolved]] Extract 3 Q4

Exercise – Reassign a Local Variable void printOwing() { double outstanding = getOutstanding(); printBanner(); PrintDetails(outstanding); } double getOutstanding() { Enumeration e = _orders.elements(); double outstanding = 0.0; while (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } return outstanding; void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); void printBanner() { System.out.println ("**************************"); System.out.println ("***** Customer Owes ******"); Think/Pair/Share What are some Local Variables that need reassigning? Q5-1

Example: Reassigning a Local Variable Outstanding used in both places We need to return it from the extracted method Outstanding is initialized only to an obvious initial value Can initialize it only within the extracted method If something more involved happens to the variable, we have to pass in the previous value as a parameter

Exercise – Reassigned a Local Variables void printOwing(double previousAmount) { double outstanding = previousAmount; printBanner(); double outstanding = getOutstanding(); PrintDetails(outstanding); } double getOutstanding(double initialValue) { Enumeration e = _orders.elements(); double result = initialValue; while (e.hasMoreElements()) { Order each = (Order) e.nextElement(); result += each.getAmount(); } return result; void printDetails (double outstanding) { System.out.println ("name: " + _name); System.out.println ("amount " + outstanding); void printBanner() { System.out.println ("**************************"); System.out.println ("***** Customer Owes ******"); How would you clarify this version? Think/Pair/Share What are some Local Variables that need reassigning? Q5: What was done to the code to resolve the problem indicated in Question 4? Q5-2 

Inline Method Situation: A method’s body is as clear as its name – why have the method? Use short methods Needless Indirection Solution: Put the method’s body into the the body of its callers and remove the method Int getRating() { return (moreThanFiveLateDeliveries()) ? 2 :1; } boolean moreThanFiveLateDeliveries() return _numberOfLateDeliveries > 5; Q6: What is the problem with having an inline method? Int getRating() { return (_numberOfLateDeliveries > 5) ? 2 :1; } Q6 

Inline Temp Situation: Temp assigned to once with a simple expression, and temp getting in the way of other refactorings? Solution: Replace all references to the temp with the expression. double basePrice = anOrder.basePrice(); return (basePrice > 100); … return (anOrder.basePrice() > 100); …

Replace Temp with Query Situation: Using a temporary variable to hold the result of an expression unnecessarily Solution: Extract the expression into a method. Replace all references to the temp with the expression. 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; } The new method can then be used in other methods. Q7: What are the major steps in the solution when replacing a temporary variable with a query? Q7

What’s Fowler’s thing about Temp’s? Everyone defining a Temp to be something will use a different name. So, Temps complicate your ability to understand new code. Like, “How do you order a milkshake in other places?” Thickshake Frappe Malt Leche malteada Fowler’s best arguments on removing local variables are on pp 113-114. Image from http://www.chick-fil-a.com/Pressroom/Press-Releases/holiday-products-2012.

Introduce Explaining Variable Situation: You have a complicated expression. Solution: Put 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 } Woah – Fowler likes this use of Temps! 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 Variables Situation: Have a temporary variable assigned to more than once Exception: a loop nor collecting temporary variable Solution: Make a separate temporary variable for each assignment double temp = 2 * (_height + _width); System.out.println (temp); temp = _height * _width; Just say what you mean… Q8: What is the exception for Splitting Temporary Variables? final double perimeter = 2 * (_height + _width); System.out.println (perimeter); final double area = _height * _width; System.out.println (area); Q8

Remove Assignments to Parameters Situation: The code assigns to a parameter. Solution: 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.

A more detailed example – refactor? From your “swap” homework: private void setTitleMonth(int n, int year) { switch (n) { case (1): this.monthTitle.setText("January " + year); this.monthName = "January " + year; break; case (2): this.monthTitle.setText("February " + year); this.monthName = "February " + year; case (3): this.monthTitle.setText("March " + year); this.monthName = "March " + year; case (4): this.monthTitle.setText("April " + year); this.monthName = "April " + year; case (5): …

Review - Bad Smells in Code Duplicated Code Long Method Large Class Long Parameter List Divergent Change Shotgun Surgery Feature Envy Data Clumps Primitive Obsession Switch Statements Lazy Class Parallel Inheritance Hierarchies Speculative Generality Temporary Field Message Chains Middle Man Inappropriate Intimacy Incomplete Library Class Data Class Refused Bequest Alternative Classes w/ varied interfaces Comments Talk to the left column today… We addressed some of these with the refactorings today! More to come… 