Introduction to Refactoring

52 %
48 %
Information about Introduction to Refactoring
Technology

Published on March 3, 2014

Author: nverdo

Source: slideshare.net

Description

Introduction to refactoring, covering the SOLID principles, some examples of code smells and refactoring examples.

SOLID OO design principles:
- Single Responsibility Principle
- Open Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle

Code Smells:
- Comments
- Long Method
- Long Parameter List
- Duplicated Code
- Large Class
- Type Embedded in Name
- Uncommunicative Name
- Inconsistent Names
- Dead Code
- Speculative Generality

Refactorings:
- Rename Method
- Extract Method
- Replace Temp With Query
- Introduce Parameter Object
- Extract Class
- Extract Subclass
- Replace Parameter with Method
- Substitute Algorithm

Refactoring Improving the design of existing code … …. without changing the behavior! agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Why do good developers write bad software? • Project and budget pressure lead to taking shortcuts • You realize there are better ways to do something • Requirements change over time ! • When it’s hard to change update your code this lead to less optimal design e fix our w How do ? oftware s agile42 | The Agile Coaching Company How do w e know ou r software is “bad” … when it works fin e! www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Software development is not a Jenga game • Single Responsibility Principle • Just because you can, doesn’t mean you should. • Open Closed Principle • Open chest surgery is not needed when putting on a coat. • Liskov Substitution Principle • If it looks like a duck, quacks like a duck,
 but needs batteries – you probably have the wrong abstraction • Interface Segregation Principle • You want me to plug this in, where? • Dependency Inversion Principle • Would you solder a lamp directly to the electrical wiring in a wall? agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Single Responsibility Principle • A responsibility can be defined as a reason to change ! ! ! ! ! ! ! • Just because you can, doesn’t mean you should. agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Open Closed Principle • open for extension, but closed for modification ! ! ! ! ! ! ! • Open chest surgery is not needed when putting on a coat. agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Liskov Substitution Principle • use a subtype without changing the correctness of the program ! ! ! ! ! ! ! • If it looks like a duck, quacks like a duck,
 but needs batteries – you probably have the wrong abstraction agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Interface Segregation Principle • states that no client should be forced to depend on methods it does not use ! ! ! ! ! ! ! • You want me to plug this in, where? agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Dependency Inversion Principle • no dependencies on implementations only on abstractions ! ! ! ! ! ! ! • Would you solder a lamp directly to the electrical wiring in a wall? agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Dependency Inversion Example class EventLogWriter { public void Write(string message) { //Write to event log here } } ! class AppPoolWatcher { // Handle to EventLog writer to write to the logs EventLogWriter writer = null; ! // This function will be called when the app pool has problem public void Notify(string message) { if (writer == null) { writer = new EventLogWriter(); } writer.Write(message); } } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Dependency Inversion Example EventLogWriter AppPoolWatcher // This can be watcher.Action ! writer = new EventLogWriter(); watcher = new AppPoolWatcher(); done in some class = writer; // This can be done in some other class watcher.Notify("Sample message to log"); agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Dependency Inversion Example class AppPoolWatcher { // Handle to EventLog writer to write to the logs INofificationAction action = null; ! ! public INofificationAction Action { get { return action; } set { action = value; } } // This function will be called when the app pool has problem public void Notify(string message) { action.ActOnNotification(message); } } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Refactoring Improving the design of existing code Without changing the behavior agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Refactoring Released in 2000, already a golden oldie, a book I recommend everyone to read. ! The book defines the technique of refactoring and is a reference for refactoring types. agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Code Smells Refactoring Cheat Codes agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Code Smells • The term code smells was introduced by Kent Beck, based on an important lesson he learned from his Grandmother about children and diapers.
 
 „If it stinks, change it”—Grandma Beck agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Code Smells • Duplicated Code • Primitive Obsession • Inappropriate Intimacy • Long Method • Switch Statements • Large Class • Parallel Inheritance Hierarchies • Alternative Classes with Different Interfaces • Long Parameter List • Divergent Change • Shotgun Surgery • Feature Envy • Data Clumps agile42 | The Agile Coaching Company • Incomplete Library Class • Lazy Class • Data Class • Speculative Generality • Refused Bequest • Temporary Field • Comments • Middle Man • Dead Code www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Comments and Naming • Comments • Rename Method • Add comments only to explain purpose • Extract Method • If comments need to explain how code work, it smells. ! • Instead use meaningful names, e.g.:
 schedule.add(Course course) ! ! ! ! ! ! • Type Embedded in Name • Rename Method • Uncommunicative Name • Inconsistent Names agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Excess and Duplication • Excess • Long Method • Long Parameter List • Large Class • Long methods, large classes and endless parameters make code unreadable. ! • Duplicated Code • Extract Method • Replace Temp with Query • Introduce Parameter Object • Extract Class • Extract Subclass ! ! ! • Replace Parameter with Method • Pull Up Field • Form Template Method • Substitute Algorithm agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

The Past and the Future • Dead Code • Delete Code • or worse, commented code ! • Delete it, we have version control for that! ! ! ! • Speculative Generality • Collapse Hierarchy • Don't attempt to predict future needs with unnecessary generalization. • Inline Class • Remove Parameter • Rename Method YAGNI! agile42 | The Agile Coaching Company KISS www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Rename Method // this method will return the maximum void getMaximumCreditLimit() { // credit limit. return maximumCreditLimit; void getIt() { } return _mCL; void getInvoiceCreditLimit() { } int maximumCredit; void getivcdlmt() { float usedCredit; int m; float u; => . . } . . } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Extract Method void printOwing(double amount) { void printOwing(double amount) { printBanner(); printBanner(); printDetails(amount); //print details } System.out.println ("name:" + _name); System.out.println ("amount" + amount); } void printDetails (double amount) { => System.out.println ("name:" + _name); System.out.println ("amount" + amount); } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Replace Temp With Query double basePrice = _quantity * _itemPrice; if (basePrice() > 1000) if (basePrice > 1000) return basePrice() * 0.95; return basePrice * 0.95; else else return basePrice() * 0.98; return basePrice * 0.98; … double basePrice() { => return _quantity * _itemPrice; } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Introduce Parameter Object double invoicedAmount(Date start, Date end) { double invoicedAmount(Period range) { double result; double result; for (Invoice invoice: invoices) { for (Invoice invoice: invoices) { if (range.contains(invoice.getDate()) { if (invoice.getDate().after(start) || result += invoice.getAmount(); invoice.getDate().before(end)) { } result += invoice.getAmount(); } } return result; } return result; } => ! } class Period (Date start, Date end) { . . . boolean contains(Date date) { return date.after(start) || date.before(end); } } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Extract Class class Person... public String getName() { class Person... public String getName() { return _name; } public String getTelephoneNumber() { return ("(" + _officeAreaCode + ")" + _officeNumber); } String getOfficeAreaCode() { return _officeAreaCode; } String getOfficeNumber() { return _officeNumber; } private String _name; private String _officeAreaCode; private String _officeNumber; agile42 | The Agile Coaching Company return _name; => ! } public String getTelephoneNumber(){ return _officeTelephone.getTelephoneNumber(); } TelephoneNumber getOfficeTelephone() { return _officeTelephone; } private String _name; private TelephoneNumber _officeTelephone = new TelephoneNumber(); class TelephoneNumber... public String getTelephoneNumber() { return ("(" + _areaCode + ") " + _number); } String getAreaCode() { return _areaCode; String getNumber() { return _number; } private String _number; private String _areaCode; www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Extract Subclass class JobItem ... public JobItem (int unitPrice, class JobItem ... public JobItem (int unitPrice) { boolean isLabor, Employee employee) { _unitPrice = unitPrice; _isLabor = isLabor; _employee = employee; ! } public int getUnitPrice(){ return (_isLabor) ? _employee.getRate(): _unitPrice; } ... class Employee... public Employee (int rate) { _rate = rate; } public int getRate() { return _rate; } private int _rate; _unitPrice = unitPrice; ! => } public int getUnitPrice(){ return _unitPrice; } ... class LaborItem ... public LaborItem (Employee employee) { super(0); _employee = employee; } public int getUnitPrice(){ return_employee.getRate(): } ... ! class Employee... public Employee (int rate) { _rate = rate; } public int getRate() { return _rate; } private int _rate; agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Replace Parameter with Method public double getPrice() { int basePrice = _quantity * _itemPrice; int discountLevel; if (_quantity > 100) discountLevel = 2; else discountLevel = 1; double finalPrice = discountedPrice (basePrice,discountLevel); return finalPrice; } ! private double discountedPrice (int basePrice, int discountLevel) { if (discountLevel == 2) return basePrice * 0.1; else return basePrice * 0.05; } agile42 | The Agile Coaching Company public double getPrice() { if (getDiscountLevel() == 2) return getBasePrice() * 0.1; else return getBasePrice() * 0.05; } ! => private double getBasePrice() { return _quantity * _itemPrice; } ! private int getDiscountLevel() { if (_quantity > 100) return 2; else return 1; } www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Substitute Algorithm String foundPerson(String[] people){ for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){ return "Don"; } if (people[i].equals ("John")){ return "John"; } if (people[i].equals ("Kent")){ return "Kent"; } } return ""; } => String foundPerson(String[] people){ List candidates = Arrays.asList(new String[] {"Don", "John", "Kent"}); for (int i=0; i &lt; people.length; i++) if (candidates.contains(people[i])) return people[i]; return ""; } agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

References • SOLID:
 http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) ! • SmellsToRefactorings:
 http://users.csc.calpoly.edu/~jdalbey/305/Lectures/SmellsToRefactorings ! • Martin Fowler refactoring site: http://refactoring.com/ ! • Dependency Injection: http://martinfowler.com/articles/injection.html agile42 | The Agile Coaching Company www.agile42.com | All rights reserved. Copyright © 2007 - 2014.

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

Introduction to Refactoring - Design Principles

The process of refactoring involves the removal of duplication, the simplification of complex logic, and the clarification of unclear code. When you ...
Read more

Refactoring: Improving the Design of Existing Code (Object ...

Besides an introduction to refactoring, this handbook provides a catalog of dozens of tips for improving code.
Read more

Introduction to Refactoring to Patterns | What Is ...

Refactoring software by hand can be a real pain. So why not just automate the process? In this chapter, Joshua Kerievsky explains the whys and hows of ...
Read more

1. Introduction to Refactoring - Refactoring with ...

Chapter 1. Introduction to Refactoring Refactoring is the process of changing a software system in such a way that it does not alter the external behavior ...
Read more

Introduction to Refactoring - JEXP

Next: Introduction Up: Refactoring Benefits and Disadvantages Previous: Intention of this paper ... Introduction; What is Refactoring? Testing using Unit Tests
Read more

.NET Refactoring - JustCode | Telerik

Introduction to Refactoring. What is refactoring? Code refactoring is a technique used to change the structure and appearance of the code, ...
Read more

SourceMaking: Refactoring - Design Patterns & Refactoring

The refactoring techniques in this group streamline methods, remove code duplication, ... Introduction Introduction to the Case Study
Read more

Introduction to Software Engineering/Testing/Refactoring ...

Code refactoring is "a disciplined way to restructure code", undertaken in order to improve some of the nonfunctional attributes of the software.
Read more

Introduction to Refactoring - Black Bytes

If you aren’t familiar with the term, refactoring is the act of improving the quality of code without changing what it does. This will make your code a ...
Read more

Refactoring: Improving the Design of Existing Code ...

Besides an introduction to what refactoring is, this handbook provides a catalogue of dozens of tips for improving code.
Read more