SlideShare a Scribd company logo
RefactoringChapter 9Simplifying Conditional Expressions
Read thisand then read thisDecompose Conditionalif (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);
Consolidate Conditional ExpressionBefore:After:double disabilityAmount() {       if (_seniority < 2) return 0;       if (_monthsDisabled > 12) return 0;       if (_isPartTime) return 0;       // ...}double disabilityAmount() {       if (isNotEligableForDisability()) return 0;       // ...}
Beforeif (isSpecialDeal()) {doSomePreparation();doNonRelatedWork();	total = price * 0.95;	send();doSomeCleanUp();}else {doSomePreparation();	total = price * 0.98;	send();doNonRelatedWork();doSomeCleanUp();}Consolidate Duplicate Conditional Fragments
Consolidate Duplicate Conditional FragmentsAfterdoNonRelatedWork();doSomePreparation();if (isSpecialDeal()) 	total = price * 0.95;else	total = price * 0.98;send();doSomeCleanUp();
Remove Control FlagTrace thisvoid 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;			}		}	}}
Remove Control Flag○use return, break, continue …✕set a flag and check somewhere later
Alternative 1:Remove Control Flagvoid 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;		}	}}
Alternative 2:Remove Control Flagvoid checkSecurity(String[] people) {	String found = foundMiscreant(people);someLaterCode(found);}String foundMiscreant(String[] people) {	for (int i = 0; i < people.length; i++) {		if (people[i].equals ("Don")){sendAlert();			return "Don";		}		if (people[i].equals ("John")){sendAlert();			return "John";		}	}	return "";}
BeforeReplace Nested Conditional with Guard Clausesdouble getPayAmount() {	double result;	if (_isDead) {		result = deadAmount();	} else {		if (_isSeparated) {		result = separatedAmount();		} else {			if (_isRetired) result = retiredAmount();			else result = normalPayAmount();		}	}	return result;}
AfterReplace Nested Conditional with Guard Clausesdouble getPayAmount() {	if (_isDead)		return deadAmount();	if (_isSeparated)		return separatedAmount();	if (_isRetired)		return retiredAmount();	return normalPayAmount();};
Mind implicit semanticsGuard clause-> (somehow) exceptional conditionif else-> two equivalent normal conditionsReplace Nested Conditional with Guard Clauses
Replace Nested Conditional with Guard ClausesHowever, you might have seen this …if (aquireResource1()) {	if (aquireResource2()) {if (aquireResource3()){		if (aquireResource4()) {			doRealWork();releaseResource4();		}			releaseResource3();	}	releaseResource2();	}releaseResource1();}
Replace Nested Conditional with Guard Clausesor this …if (false == aquireResource1())return;if (false == aquireResource2()) {releaseResource1();	return;}if (false == aquireResource3()){releaseResource2();releaseResource1();return;}doRealWork();releaseResource3();releaseResource2();releaseResource1();return;
BeforeReplace Conditional with Polymorphismclass Employee...    int payAmount(Employee) {        switch (getType()) {            case EmployeeType.ENGINEER:               return _monthlySalary;            case EmployeeType.SALESMAN:               return _monthlySalary + _commission;            case EmployeeType.MANAGER:               return _monthlySalary + _bonus;            default:               throw new RuntimeException("Incorrect Employee");        }    }
!○Polymorphism might be better, usuallyReplace Conditional with Polymorphismswitch caseclauses
class Employee...intpayAmount() {        return _type.payAmount(this);}class Salesman...intpayAmount(Employee emp) {        return emp.getMonthlySalary() + emp.getCommission();    }class Manager...intpayAmount(Employee emp) {        return emp.getMonthlySalary() + emp.getBonus();    }AfterReplace Conditional with Polymorphism
Same with Replace Conditional with Polymorphism
deal with special cases extensively checked
check type -> check NULL
Before:Introduce Null Objectclass Customer...    public String getName() {...}    public BillingPlangetPlan() {...}    public PaymentHistorygetHistory() {...}if (customer == null) plan = BillingPlan.basic();else plan = customer.getPlan();
AfterIntroduce Null Objectplan = customer.getPlan();class NullCustomer...    public BillingPlangetPlan(){        return BillingPlan.basic();    }

More Related Content

PPTX
重構—改善既有程式的設計(chapter 8)part 2
PPTX
重構—改善既有程式的設計(chapter 8)part 1
PPT
FP 201 Unit 2 - Part 3
PPT
FP 201 Unit 3
PDF
C++ aptitude
PDF
Tdd.eng.ver
PPTX
Writing Good Tests
PPT
data Structure Lecture 1
重構—改善既有程式的設計(chapter 8)part 2
重構—改善既有程式的設計(chapter 8)part 1
FP 201 Unit 2 - Part 3
FP 201 Unit 3
C++ aptitude
Tdd.eng.ver
Writing Good Tests
data Structure Lecture 1

What's hot (20)

PDF
Clean coding-practices
DOC
12. stl örnekler
PPTX
Linq Sanjay Vyas
PPTX
classes & objects in cpp overview
PPTX
clean code book summary - uncle bob - English version
PPTX
Presentacion clean code
 
DOCX
Memory management in c++
PPT
Csharp In Detail Part1
PPTX
Pro typescript.ch03.Object Orientation in TypeScript
PDF
Extend GraphQL with directives
PDF
Welcome to Modern C++
PDF
C++aptitude questions and answers
PPTX
C++11 - STL Additions
PDF
PPT
Lecture04
KEY
What's New In Python 2.6
PPTX
Clean Code Development
PPT
Memory Management In C++
PDF
PDF
Rechecking SharpDevelop: Any New Bugs?
Clean coding-practices
12. stl örnekler
Linq Sanjay Vyas
classes & objects in cpp overview
clean code book summary - uncle bob - English version
Presentacion clean code
 
Memory management in c++
Csharp In Detail Part1
Pro typescript.ch03.Object Orientation in TypeScript
Extend GraphQL with directives
Welcome to Modern C++
C++aptitude questions and answers
C++11 - STL Additions
Lecture04
What's New In Python 2.6
Clean Code Development
Memory Management In C++
Rechecking SharpDevelop: Any New Bugs?
Ad

Viewers also liked (9)

PPTX
重構—改善既有程式的設計(chapter 4,5)
PPTX
重構—改善既有程式的設計(chapter 7)
PPTX
重構—改善既有程式的設計(chapter 2,3)
PPTX
重構—改善既有程式的設計(chapter 12,13)
PPTX
Approaching real-time-hadoop
PPTX
重構—改善既有程式的設計(chapter 6)
PPTX
Real time big data applications with hadoop ecosystem
PPTX
重構—改善既有程式的設計(chapter 1)
PPTX
A Graph Service for Global Web Entities Traversal and Reputation Evaluation B...
重構—改善既有程式的設計(chapter 4,5)
重構—改善既有程式的設計(chapter 7)
重構—改善既有程式的設計(chapter 2,3)
重構—改善既有程式的設計(chapter 12,13)
Approaching real-time-hadoop
重構—改善既有程式的設計(chapter 6)
Real time big data applications with hadoop ecosystem
重構—改善既有程式的設計(chapter 1)
A Graph Service for Global Web Entities Traversal and Reputation Evaluation B...
Ad

Similar to 重構—改善既有程式的設計(chapter 9) (20)

PDF
$q and Promises in AngularJS
PDF
Dutch php a short tale about state machine
ODP
PHPUnit elevato alla Symfony2
PPTX
Adding Dependency Injection to Legacy Applications
PDF
package employeeType.employee;public class Employee {    private.pdf
PDF
Command Bus To Awesome Town
DOCX
Simple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docx
PPT
Topic12Conditional if else Execution.ppt
PPT
Topic12ConditionalExecution.ppt
PDF
Martin Fowler's Refactoring Techniques Quick Reference
PPT
Oracle PL/SQL - Creative Conditional Compilation
PDF
package employeeType.employee;public class Employee {   private .pdf
PDF
Refactoring Example
PDF
Ngrx slides
PDF
Recompacting your react application
KEY
PHPSpec BDD for PHP
PDF
I need help creating a basic and simple Java program. Here is the ex.pdf
DOCX
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
PDF
Higher-Order Components — Ilya Gelman
PDF
Et si on en finissait avec CRUD ?
$q and Promises in AngularJS
Dutch php a short tale about state machine
PHPUnit elevato alla Symfony2
Adding Dependency Injection to Legacy Applications
package employeeType.employee;public class Employee {    private.pdf
Command Bus To Awesome Town
Simple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docx
Topic12Conditional if else Execution.ppt
Topic12ConditionalExecution.ppt
Martin Fowler's Refactoring Techniques Quick Reference
Oracle PL/SQL - Creative Conditional Compilation
package employeeType.employee;public class Employee {   private .pdf
Refactoring Example
Ngrx slides
Recompacting your react application
PHPSpec BDD for PHP
I need help creating a basic and simple Java program. Here is the ex.pdf
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
Higher-Order Components — Ilya Gelman
Et si on en finissait avec CRUD ?

More from Chris Huang (19)

PDF
Data compression, data security, and machine learning
PDF
Kks sre book_ch10
PDF
Kks sre book_ch1,2
PPTX
20130310 solr tuorial
PDF
Scaling big-data-mining-infra2
PPT
Applying Media Content Analysis to the Production of Musical Videos as Summar...
PDF
Wissbi osdc pdf
PDF
Hbase status quo apache-con europe - nov 2012
PDF
Hbase schema design and sizing apache-con europe - nov 2012
PPTX
重構—改善既有程式的設計(chapter 10)
PDF
Designs, Lessons and Advice from Building Large Distributed Systems
PPTX
Hw5 my house in yong he
PPTX
Social English Class HW4
PPTX
Social English Class HW3
PDF
Sm Case1 Ikea
PPTX
火柴人的故事
PPTX
中德文化比較
PDF
Sm Case4 Fuji Xerox
PDF
Disney報告 最終版
Data compression, data security, and machine learning
Kks sre book_ch10
Kks sre book_ch1,2
20130310 solr tuorial
Scaling big-data-mining-infra2
Applying Media Content Analysis to the Production of Musical Videos as Summar...
Wissbi osdc pdf
Hbase status quo apache-con europe - nov 2012
Hbase schema design and sizing apache-con europe - nov 2012
重構—改善既有程式的設計(chapter 10)
Designs, Lessons and Advice from Building Large Distributed Systems
Hw5 my house in yong he
Social English Class HW4
Social English Class HW3
Sm Case1 Ikea
火柴人的故事
中德文化比較
Sm Case4 Fuji Xerox
Disney報告 最終版

Recently uploaded (20)

PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPTX
Cell Structure & Organelles in detailed.
PDF
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
PDF
Insiders guide to clinical Medicine.pdf
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
Mark Klimek Lecture Notes_240423 revision books _173037.pdf
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PDF
Abdominal Access Techniques with Prof. Dr. R K Mishra
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PPTX
Institutional Correction lecture only . . .
PPTX
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
Classroom Observation Tools for Teachers
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PPTX
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
Cell Structure & Organelles in detailed.
ANTIBIOTICS.pptx.pdf………………… xxxxxxxxxxxxx
Insiders guide to clinical Medicine.pdf
Pharmacology of Heart Failure /Pharmacotherapy of CHF
Mark Klimek Lecture Notes_240423 revision books _173037.pdf
Microbial diseases, their pathogenesis and prophylaxis
Abdominal Access Techniques with Prof. Dr. R K Mishra
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
Supply Chain Operations Speaking Notes -ICLT Program
Institutional Correction lecture only . . .
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
Renaissance Architecture: A Journey from Faith to Humanism
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
Classroom Observation Tools for Teachers
O5-L3 Freight Transport Ops (International) V1.pdf
STATICS OF THE RIGID BODIES Hibbelers.pdf
Introduction_to_Human_Anatomy_and_Physiology_for_B.Pharm.pptx

重構—改善既有程式的設計(chapter 9)

  • 2. Read thisand then read thisDecompose Conditionalif (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);
  • 3. Consolidate Conditional ExpressionBefore:After:double disabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; // ...}double disabilityAmount() { if (isNotEligableForDisability()) return 0; // ...}
  • 4. Beforeif (isSpecialDeal()) {doSomePreparation();doNonRelatedWork(); total = price * 0.95; send();doSomeCleanUp();}else {doSomePreparation(); total = price * 0.98; send();doNonRelatedWork();doSomeCleanUp();}Consolidate Duplicate Conditional Fragments
  • 5. Consolidate Duplicate Conditional FragmentsAfterdoNonRelatedWork();doSomePreparation();if (isSpecialDeal()) total = price * 0.95;else total = price * 0.98;send();doSomeCleanUp();
  • 6. Remove Control FlagTrace thisvoid 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; } } }}
  • 7. Remove Control Flag○use return, break, continue …✕set a flag and check somewhere later
  • 8. Alternative 1:Remove Control Flagvoid 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; } }}
  • 9. Alternative 2:Remove Control Flagvoid checkSecurity(String[] people) { String found = foundMiscreant(people);someLaterCode(found);}String foundMiscreant(String[] people) { for (int i = 0; i < people.length; i++) { if (people[i].equals ("Don")){sendAlert(); return "Don"; } if (people[i].equals ("John")){sendAlert(); return "John"; } } return "";}
  • 10. BeforeReplace Nested Conditional with Guard Clausesdouble getPayAmount() { double result; if (_isDead) { result = deadAmount(); } else { if (_isSeparated) { result = separatedAmount(); } else { if (_isRetired) result = retiredAmount(); else result = normalPayAmount(); } } return result;}
  • 11. AfterReplace Nested Conditional with Guard Clausesdouble getPayAmount() { if (_isDead) return deadAmount(); if (_isSeparated) return separatedAmount(); if (_isRetired) return retiredAmount(); return normalPayAmount();};
  • 12. Mind implicit semanticsGuard clause-> (somehow) exceptional conditionif else-> two equivalent normal conditionsReplace Nested Conditional with Guard Clauses
  • 13. Replace Nested Conditional with Guard ClausesHowever, you might have seen this …if (aquireResource1()) { if (aquireResource2()) {if (aquireResource3()){ if (aquireResource4()) { doRealWork();releaseResource4(); } releaseResource3(); } releaseResource2(); }releaseResource1();}
  • 14. Replace Nested Conditional with Guard Clausesor this …if (false == aquireResource1())return;if (false == aquireResource2()) {releaseResource1(); return;}if (false == aquireResource3()){releaseResource2();releaseResource1();return;}doRealWork();releaseResource3();releaseResource2();releaseResource1();return;
  • 15. BeforeReplace Conditional with Polymorphismclass Employee... int payAmount(Employee) { switch (getType()) { case EmployeeType.ENGINEER: return _monthlySalary; case EmployeeType.SALESMAN: return _monthlySalary + _commission; case EmployeeType.MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } }
  • 16. !○Polymorphism might be better, usuallyReplace Conditional with Polymorphismswitch caseclauses
  • 17. class Employee...intpayAmount() { return _type.payAmount(this);}class Salesman...intpayAmount(Employee emp) { return emp.getMonthlySalary() + emp.getCommission(); }class Manager...intpayAmount(Employee emp) { return emp.getMonthlySalary() + emp.getBonus(); }AfterReplace Conditional with Polymorphism
  • 18. Same with Replace Conditional with Polymorphism
  • 19. deal with special cases extensively checked
  • 20. check type -> check NULL
  • 21. Before:Introduce Null Objectclass Customer... public String getName() {...} public BillingPlangetPlan() {...} public PaymentHistorygetHistory() {...}if (customer == null) plan = BillingPlan.basic();else plan = customer.getPlan();
  • 22. AfterIntroduce Null Objectplan = customer.getPlan();class NullCustomer... public BillingPlangetPlan(){ return BillingPlan.basic(); }
  • 23. Write your assumption explicitly and clearlyIntroduce Assertion double getExpenseLimit() {// should have either expense limit or a primary project return (_expenseLimit != NULL_EXPENSE) ? _expenseLimit: _primaryProject.getMemberExpenseLimit();} double getExpenseLimit() {Assert.isTrue (_expenseLimit != NULL_EXPENSE || _primaryProject != null); return (_expenseLimit != NULL_EXPENSE) ? _expenseLimit: _primaryProject.getMemberExpenseLimit();}
  • 24. Do NOT overuseIf code does work without the assertion, remove it.Introduce Assertion
  • 25. NotesSave brain powerBreak/prune eye-tracing as early as possibleDon’t Repeat Yourself