Catalog of Refactoring (5) Simplifying Conditional Expressions.

Slides:



Advertisements
Similar presentations
ICE1341 Programming Languages Spring 2005 Lecture #13 Lecture #13 In-Young Ko iko.AT. icu.ac.kr iko.AT. icu.ac.kr Information and Communications University.
Advertisements

Control Structures Any mechanism that departs from straight-line execution: –Selection: if-statements –Multiway-selection: case statements –Unbounded iteration:
Expressions and Statements. 2 Contents Side effects: expressions and statements Expression notations Expression evaluation orders Conditional statements.
Module 7. Simplifying Conditional Expressions Course: Refactoring.
Written by: Dr. JJ Shepherd
Software Testing and Maintenance 1 Today’s Agenda  Course Evaluation  HW 4 Return  HW 5 Correction  Quiz 4 Next Class  Software Refactoring.
 Both System.out and System.err are streams—a sequence of bytes.  System.out (the standard output stream) displays output  System.err (the standard.
Intro to OOP with Java, C. Thomas Wu Inheritance and Polymorphism
Software Engineering Key Refactorings
George Blank University Lecturer. REFACTORING Improving the Design of Existing Code Supplement to Ian Sommerville, Software Engineering, Chapter 20 Prepared.
REFACTORING Improving the Design of Existing Code Atakan Şimşek e
Principles of Computer Programming (using Java) Review Haidong Xue Summer 2011, at GSU.
Unit 5 School of Information Systems & Technology1 School of Information Systems and Technology (IST)
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Liang, Introduction to Java Programming, Seventh Edition, (c) 2009 Pearson Education, Inc. All rights reserved Chapter 18 Exception Handling.
Assertions Program correctness. Assertions Java statement – enables you to assert an assumption about your program. – An assertion contains a Boolean.
Refactoring – III Measured Smells. Smells Covered 1. Comments 2. Long method 3. Large Class 462.
CPS120: Introduction to Computer Science Decision Making in Programs.
Chapter 6: Code Refactoring Omar Meqdadi SE 3860 Lecture 6 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
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 Improving the structure of existing code Refactoring1.
Refactoring1 Refactoring DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY February 6, 2009.
SWE 316: Software Design and Architecture Objectives Lecture # 20 Improving the existing design: Refactoring SWE 316: Software Design and Architecture.
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.
CPS120: Introduction to Computer Science Decision Making in Programs.
Refactoring Deciding what to make a superclass or interface is difficult. Some of these refactorings are helpful. Some research items include Inheritance.
Lecture 4 Control Structures MIT – AITI What are Control Structures? Control structures are a way to alter the natural sequence of execution in.
Today’s Agenda  More refactoring patterns Software Testing and Maintenance 1.
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.
Programming with Assertions © Allan C. Milne v
NJIT 1 Test Driven Development and Refactoring Larman, Chapter 21.
Refactoring Conditionals Lesson Five: Conditionals.
Exceptions and Assertions Chapter 15 – CSCI 1302.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
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.
 Control Flow statements ◦ Selection statements ◦ Iteration statements ◦ Jump statements.
CPS120: Introduction to Computer Science Decision Making in Programs.
CSSE 375 Organizing Data – Part 2 Shawn and Steve Continue the same quiz!
Refactoring1 Improving the structure of existing code.
Refactoring. 2 Process of changing a software system in such a way that it does not alter the external behavior of the code, yet improves its internal.
CS2102: Lecture on Abstract Classes and Inheritance Kathi Fisler.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
Written by: Dr. JJ Shepherd
Software Construction and Evolution - CSSE 375 Simplifying Conditionals Shawn & Steve.
CSSE 375 Organizing Data – Part 1 Shawn and Steve Q1.
REFACTORING CHANGE VALUE TO REFERENCE SUBSTITUTE ALGORITHM REPLACE CONDITIONAL WITH POLYMORHPISM.
CPS120: Introduction to Computer Science Decision Making in Programs.
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.
(c) University of Washington10-1 CSC 143 Java Errors and Exceptions Reading: Ch. 15.
Module 9. Dealing with Generalization Course: Refactoring.
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.
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.
Exceptions in the Java programming language J. W. Rider.
Catalog of Refactoring (6) Making Method Calls Simpler.
Discussion 4 eecs 183 Hannah Westra.
Inheritance and Polymorphism
SWEN-610 Foundations of Software Engineering
More Selections BIS1523 – Lecture 9.
null, true, and false are also reserved.
Conditional Statements
Unit 3 - The while Loop - Extending the Vic class - Examples
Improving the structure of existing code
Refactoring Strategies
Java Statements B.Ramamurthy CS114A, CS504 4/23/2019 BR.
Controlling Program Flow
Presentation transcript:

Catalog of Refactoring (5) Simplifying Conditional Expressions

Catalog Decompose Conditional Consolidate Conditional Expression Consolidate Duplicate Conditional Fragments Replace Nested Conditional with Guard Clauses Remove Control Flag Replace Conditional with Polymorphism Introduce Null Object

Decompose Conditional You have a complicated conditional (if- then-else) statement. Extract methods from the condition, then part, and else parts.

Motivation One of he most common areas of complexity in a program lies in complex conditional logic –code, both in the condition checks and in the actions, tells you what happens but can easily obscure why it happens. Clearer code after decomposing it and them replacing with method calls named after the intention of that block of code

Mechanics 1.Extract the condition into its own method. 2.Extract the then part and the else part into their own methods. 3.Compile and test

Example if (date.before (SUMMER_START) || date.after(SUMMER_END)) charge = quantity * _winterRate + _winterServiceCharge; else charge = quantity * _summerRate; if (notSummer(date)) charge = winterCharge(quantity); else charge = summerCharge (quantity); private boolean notSummer(Date date) { return date.before (SUMMER_START) || date.after(SUMMER_END); } private double summerCharge(int quantity) { return quantity * _summerRate; } private double winterCharge(int quantity) { return quantity * _winterRate + _winterServiceCharge; }

Consolidate Conditional Expression You have a sequence of conditional tests with the same result. Combine them into a single conditional expression and extract it.

Motivation If different checks results in same action, the proper logic is perhaps one check with or clauses. –It may not be when the checks are independent As a setup for method extraction

Mechanism 1.Check that none of the conditionals has side effects. 2.Replace the string of conditionals with a single conditional statement using logical operators. 3.Compile and test.

double disabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; // compute the disability amount... Example double disabilityAmount() { if ((_seniority 12) || (_isPartTime)) return 0; // compute the disability amount...

if (onVacation()) if (lengthOfService() > 10) return 1; return 0.5; Example if (onVacation() && lengthOfService() > 10) return 1; else return 0.5; return (onVacation() && lengthOfService() > 10) ? 1 : 0.5;

Consolidate Duplicate Conditional Fragments The same fragment of code is in all branches of a conditional expression. Move it outside of the expression.

Mechanism 1.Identify code that is executed the same way regardless of the condition 2.If the common code is at the beginning, move it to before the conditional. 3.If the common code is at the end, move it to after the conditional. 4.If the common code is in the middle, look to see whether the code before or after it changes anything. If it does, you can move the common code forward or backward to the ends. You can then move it as described for code at the end or the beginning. 5.If there is more than a single statement, you should extract that code into a method 6.Compile and test.

if (isSpecialDeal()) { total = price * 0.95; send(); } else { total = price * 0.98; send(); } Example if (isSpecialDeal()) total = price * 0.95; else total = price * 0.98; send();

Remove Control Flag You have a variable that is acting as a control flag for a series of boolean expressions. Use a break or return instead.

Motivation set done to false while not done if (condition) do something set done to true next step of loop Relic of structural programming that require single exit point Error prone

Mechanism 1.Find the value of the control flag that gets you out of the logic statement. 2.Replace assignments of the break-out value with a break or continue statement. 3.Compile and test. 1.Extract the logic into a method. 2.Find the value of the control flag that gets you out of the logic statement. 3.Replace assignments of the break-out value with a return. 4.Compile and test. or

Example void checkSecurity(String[] people) { boolean found = false; for (int i = 0; i < people.length; i++) { if (! found) { if (people[i].equals ("Don")){ sendAlert(); found = true; } if (people[i].equals ("John")){ sendAlert(); found = true; }

Example void checkSecurity(String[] people) { for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){ sendAlert(); break; } if (people[i].equals ("John")){ sendAlert(); break; }

Replace Nested Conditional with Guard Clauses A method has conditional behavior that does not make clear the normal path of execution. Use guard clauses for all the special cases.

Example double getPayAmount() { double result; if (_isDead) result = deadAmount(); else { if (_isSeparated) result = separatedAmount(); else { if (_isRetired) result = retiredAmount(); else result = normalPayAmount(); }; } return result; } double getPayAmount() { if (_isDead) return deadAmount(); if (_isSeparated) return separatedAmount(); if (_isRetired) return retiredAmount(); return normalPayAmount(); }

Motivation Two kinds of conditional expression –Check normal condition –Check exception / unusual conditions Guard clause

Mechanism 1.For each check put in the guard clause. The guard clause either returns, or throws an exception 2.Compile and test after each check is replaced with a guard clause.

Another Example Reverse Conditions public double getAdjustedCapital() { double result = 0.0; if (_capital > 0.0) { if (_intRate > 0.0 && _duration > 0.0) { result = (_income / _duration) * ADJ_FACTOR; } return result; } public double getAdjustedCapital() { if (_capital <= 0.0) return 0.0; if (_intRate <= 0.0 || _duration <= 0.0) return 0.0; return (_income / _duration) * ADJ_FACTOR; }

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.

Motivation Conditionals on type code or string are better handled with by OOP type system. –Extensibility –Maintainability

Mechanism 1.If the conditional statement is one part of a larger method, take apart the conditional statement and use Extract Method. 2.If necessary use Move Method to place the conditional at the top of the inheritance structure.. 3.Pick one of the subclasses. Create a subclass method that overrides the conditional statement method. Copy the body of that leg of the conditional statement into the subclass method and adjust it to fit. 4.Remove the copied leg of the conditional statement.. 5.Repeat with each leg of the conditional statement until all legs are turned into subclass methods. 6.Compile and test every step.

Example class Employee... int payAmount() { return _type.payAmount(this); } int getType() { return _type.getTypeCode(); } private EmployeeType _type;... abstract class EmployeeType... abstract int getTypeCode(); int payAmount(Employee emp) { switch (getTypeCode()) { case ENGINEER: return emp.getMonthlySalary(); case SALESMAN: return emp.getMonthlySalary() + emp.getCommission(); case MANAGER: return emp.getMonthlySalary() + emp.getBonus(); default: throw new RuntimeException("Incorrect Employee"); } class Engineer extends EmployeeType... int getTypeCode() { return Employee.ENGINEER; }...

class Engineer... int payAmount(Employee emp) { return emp.getMonthlySalary(); } class Salesman... int payAmount(Employee emp) { return emp.getMonthlySalary() + emp.getCommission(); } class Manager... int payAmount(Employee emp) { return emp.getMonthlySalary() + emp.getBonus(); } class EmployeeType... abstract int payAmount(Employee emp);

Introduce Null Object You have repeated checks for a null value. Replace the null value with a null object.

Motivation Lots of code in the system would check objects for presence before sending a message to the object Null object knows how to handle messages –No need for system to check anymore

Mechanism 1.Create a subclass of the source class to act as a null version of the class. Create an isNull operation on the source class and the null class. 2.Find all places that can give out a null when asked for a source object. Replace them to give out a null object instead. 3.Find all places that compare a variable of the source type with null and replace them with a call isNull A few assertions that check for null in places where you should no longer see it can be useful 4.Look for cases in which clients invoke an operation if not null and do some alternative behavior if null. 5.For each of these cases override the operation in the null class with the alternative behavior. 6.Remove the condition check for those that use the overriden behavior. 7.Compile and test every step.

Example Customer customer = site.getCustomer(); BillingPlan plan; if (customer == null) plan = BillingPlan.basic(); else plan = customer.getPlan();... String customerName; if (customer == null) customerName = "occupant"; else customerName = customer.getName();... int weeksDelinquent; if (customer == null) weeksDelinquent = 0; else weeksDelinquent = customer.getHistory().getWeeksDelinquentInLastYear();

Example interface Nullable { boolean isNull(); } class Customer implements Nullable static Customer newNull() { return new NullCustomer(); } public boolean isNull() { return false; } … class NullCustomer extends Customer { public boolean isNull() { return true; } … Customer customer = site.getCustomer(); BillingPlan plan; if (customer.isNull()) plan = BillingPlan.basic(); else plan = customer.getPlan();... String customerName; if (customer.isNull()) customerName = "occupant"; else customerName = customer.getName();...

Introduce Assertion A section of code assumes something about the state of the program. Make the assumption explicit with an assertion.

Motivation Making assumptions explicit Assertions act as communication and debugging aids

Example class Employee... private static final double NULL_EXPENSE = -1.0; private double _expenseLimit = NULL_EXPENSE; private Project _primaryProject; double getExpenseLimit() { return (_expenseLimit != NULL_EXPENSE) ? _expenseLimit: _primaryProject.getMemberExpenseLimit(); } boolean withinLimit (double expenseAmount) { return (expenseAmount <= getExpenseLimit()); } double getExpenseLimit() { Assert.isTrue (Assert.ON && (_expenseLimit != NULL_EXPENSE || _primaryProject != null)); return (_expenseLimit != NULL_EXPENSE) ? _expenseLimit: _primaryProject.getMemberExpenseLimit(); }