SWEN-610 Foundations of Software Engineering

Slides:



Advertisements
Similar presentations
Module 7. Simplifying Conditional Expressions Course: Refactoring.
Advertisements

Test-Driven Development and Refactoring CPSC 315 – Programming Studio.
Refactoring and Code Smells
Lectures 17 and 18 A Refactoring Micro-Example FOR0383 Software Quality Assurance 5/16/20151Dr Andy Brooks Refactoring is really easy using this tool.
Software Construction and Evolution - CSSE 375 Bad Smells in Code Shawn Bohner & Steve Chenoweth.
Software Engineering Key Refactorings
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.
XP and Refactoring David Talby. Development Methodologies The Software Crisis – 84% of software projects are not on time – 31% of software projects never.
REFACTORING Improving the Design of Existing Code Atakan Şimşek e
13-Jul-15 Refactoring II. Books Design Patterns is the classic book by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides Basically a catalog.
Algorithm Programming Coding Advices Bar-Ilan University תשס " ו by Moshe Fresko.
Maintenance Refactoring and Code Smells. Where are we? Over the semester we have talked about Software Engineering. The overall goal of software engineering.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Refactoring Cristescu Marilena. Definitions Loose Usage: Reorganize a program(or something) As a noun: a change made to the internal structure of some.
Software Refactoring Part I: Introduction Bartosz Walter Advanced Object-Oriented Design Lecture 5.
LECTURE 38: REFACTORING CSC 395 – Software Engineering.
Refactoring - A disciplined approach to rework for better design.
Refactoring Improving the structure of existing code Refactoring1.
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.
Refactoring1 Improving the structure of existing code.
Refactoring Deciding what to make a superclass or interface is difficult. Some of these refactorings are helpful. Some research items include Inheritance.
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 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.
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.
Refactoring Conditionals Lesson Five: Conditionals.
1 Software Maintenance and Evolution CSSE 575: Session 2, Part 1 Refactoring Principles Steve Chenoweth Office Phone: (812) Cell: (937)
1 Software Maintenance and Evolution CSSE 575: Session 3, Part 3 Dealing with Generalization Steve Chenoweth Office Phone: (812) Cell: (937)
SEG 4110 – Advanced Software Design and Reengineering Topic T Introduction to Refactoring.
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.
CSSE 375 Organizing Data – Part 2 Shawn and Steve Continue the same quiz!
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 CHANGE VALUE TO REFERENCE SUBSTITUTE ALGORITHM REPLACE CONDITIONAL WITH POLYMORHPISM.
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.
Catalog of Refactoring (5) Simplifying Conditional Expressions.
ICONFINDER ICONFINDER Founded Django based web application -PostgreSQL -Elasticsearch -Amazon Elastic Compute.
Catalog of Refactoring (6) Making Method Calls Simpler.
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;
Implementation Topics Describe –Characteristics of good implementations –Best practices to achieve them Understand role of comments Learn debugging techniques.
Principles and examples
Architecture Patterns and Refactoring
Reviewing Code A guide to smelling another developer’s source code.
Steve Chenoweth Office Phone: (812) Cell: (937)
Inheritance and Polymorphism
Behavioral Design Patterns
Refactoring and Code Smells
بازآرایی برنامه Code Refactoring
Code Smells 1.
Improving the structure of existing code
Refactoring and Code Smells
Advanced Programming Behnam Hatami Fall 2017.
Refactoring.
Inheritance.
Refactoring and Code Smells
Refactoring and Code Smells
Refactoring Low Level/High Level.
Refactoring.
Chapter 9: Implementation
Refactoring and Code Smells
Presentation transcript:

SWEN-610 Foundations of Software Engineering Refactoring SWEN-610 Foundations of Software Engineering

Lehmann & Belady: Laws of Software Evolution Continuing Change - Systems must be continually adapted else they become progressively less satisfactory. Increasing Complexity - As a system evolves its complexity increases unless work is done to maintain or reduce it.

Refactoring is taking software which through natural processes has lost its original clean structure…

…and restoring a clean structure.

The definitive guide to refactoring is a book by Martin Fowler. Refactoring: Improving the Design of Existing Code Martin Fowler, Addison-Wesley, 1999. See www.refactoring.com

Refactoring should only change internal structure and not observable behavior. 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

The design entropy of a software system tends to increase over time. If you no longer can see the design, how can you stay consistent to it? Design Design Time

The entropy will increase because of the typical development death spiral. Good design up front Local modifications alter the framework Short-term goals win out over structure maintenance Engineering sinks into hacking Integrity and structure fade (entropy)

A refactoring activity can remove some of that design randomness. Fix or add a feature, and break one (or two)! Refactoring Design Entropy Refactor or Redo? Time

It is usually hard to counter, “If it ain’t broke, don’t fix it.” Generally improves product quality Pay today to ease work tomorrow. May actually accelerate today’s work

Ward Cunningham’s Code Debt Metaphor Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite [refactor – ed.]. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. Entire engineering organizations can be brought to a stand-still under the debt load of an unconsolidated implementation, object-oriented or otherwise.

Refactoring does not work well as an end task because there never is any time to do it. Refactoring should be a continuous code improvement activity: If it will make adding a new feature easier. If it will aid with debugging. If it fills a design hole. As a result of code inspection. If it simply makes the code easier to understand. Do the right thing now before doing the right thing will take too much time…and be too risky!

While we are on the subject of doing the Right Thing …

Spreads design and implementation knowledge through team Code inspections have been found to be the most effective technique for early defect detection. Spreads design and implementation knowledge through team Helps mentor less experienced developers New eyes see things “old” eyes are not seeing Did your team do any code inspections on your implementation? Next time when you can not find that bug, inspect don’t debug!

Some complain that all this patterns stuff makes the code run slower. Refactored code may run slower Do you notice? Do you care? Ways to write fast code Strict time budgets  hard real-time Constant attention  optimize always (!?) Write for speed – any and all “parlor” tricks Obscures intentions Harder to upgrade code later Often does not help (80/20 rule) Performance profiling – the intelligent engineer’s guide. Make it work. Make it right. Make it fast.

If It Stinks, Change It.

There are many bad smells that get designed and coded into software. Duplicated code Long methods Large classes Long parameter lists Orthogonal purposes for a class Shotgun changes Feature envy Data clumping Primitive object avoidance Switch statements Type codes Speculative generality Middle man overuse Inappropriate intimacy Data classes Verbose comments

What can we do with the type code? If type does not affect behavior of object but type is shared Replace type code with class This allows type checking where data is shared If type effects behavior of object But never changes after instantiation Replace type code with subclasses Is modified after instantiation Replace type code with state or strategy, as appropriate if(type == TYPE_A) { code for TYPE_A … } else if(type == TYPE_B) { code for TYPE_B … } else if(type == TYPE_X) { code for TYPE_C … } else { code for unknown type … }

Replace temp with query Replace method with method object Martin Fowler’s book is a cookbook for getting rid of smells using common refactoring operations. www.refactoring.com Extract method Inline method Replace temp with query Replace method with method object Substitute algorithm Extract class Hide delegate Remove middle man Replace type code with class Replace type code with state/strategy Replace type code with subclasses Introduce parameter object Replace inheritance with delegation Plus 70 others

Refactoring Steps

A catalog of refactorings from Fowler We will look at Simplifying Conditional Expressions >> Replace Conditional with Polymorphism

Replace Conditional with Polymorphism Example Refactoring Replace Conditional with Polymorphism You have a conditional that chooses different behavior depending on the type of an object. Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.

Standard Example double getSpeed() { switch (_type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); } throw new RuntimeException ("Should be unreachable");

Mechanics of applying Replace Conditional with Polymorphism Compile and test Establish the necessary inheritance structure Extract the conditional part of a larger method into its own method (Extract Method/compile and test) Place the conditional at the top of the inheritance structure (Move Method/compile and test) Pick one of the subclasses and “move its leg” Repeat for each leg (compile and test) Make the superclass method abstract

Example: Employee Pay by Type

Example code class Employee... int payAmount() { switch (getType()) { case EmployeeType.ENGINEER: return _monthlySalary; case EmployeeType.SALESMAN: return _monthlySalary + _commission; case EmployeeType.MANAGER: + _bonus; default: throw new RuntimeException("Incorrect Employee"); } int getType() { return _type.getTypeCode(); private EmployeeType _type; abstract class EmployeeType... abstract int getTypeCode(); class Engineer extends EmployeeType int getTypeCode() { return Employee.ENGINEER; } ... and other subclasses

Natural subclass structure Case statement is already nicely extracted Observations Natural subclass structure Case statement is already nicely extracted So Move case statement to employee type That is the class that is being subclassed

Move case statement to employee type Pass employee data as an argument class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: return emp.getMonthlySalary(); case SALESMAN: return emp.getMonthlySalary() + emp.getCommission(); case MANAGER: + emp.getBonus(); default: throw new RuntimeException( "Incorrect Employee"); } Compile

Change the payAmount method in Employee to delegate to the new class Delegate to new class Change the payAmount method in Employee to delegate to the new class class Employee... int payAmount() { return _type.payAmount(this); }

Work on the case statement, one leg at a time Copy the Engineer leg of the case statement onto the Engineer class This new method overrides the case statement for engineers. Be paranoid: put a trap class Engineer... int payAmount(Employee emp) { return emp.getMonthlySalary(); } class EmployeeType... int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: throw new RuntimeException ( "Should be being overridden"); case SALESMAN: return emp.getMonthlySalary() + emp.getCommission(); case MANAGER: + emp.getBonus(); default: throw new RuntimeException("Incorrect Employee"); }

Repeat for remaining legs Compile and Test class Salesman... int payAmount(Employee emp) { return emp.getMonthlySalary() + emp.getCommission(); } class Manager... return emp.getMonthlySalary() + emp.getBonus(); Compile and Test Compile and Test

Declare the superclass method abstract class EmployeeType... abstract int payAmount(Employee emp); Compile and Test