SlideShare a Scribd company logo
1 of 102
Download to read offline
Refactoring!
How to improve your code!
ARTEM TABALIN!
What is refactoring?!
Definition. Goals. When to Refactor. Pitfalls.!
What is Refactoring?!
!
“Refactoring is a change made to the internal structure
of software to make it easier to understand and
cheaper to modify without changing its observable
behavior.”!
- Martin Fowler!
Is it just cleaning up code?!
The technique of cleaning up code in more organized
and controlled way!
The Two Hats!
Two distinct activities!
1.  adding functions
2.  refactoring!
These two activities should NOT take place at the
same time!
Goals!
•  Prevent code quality reduction!
•  Make code clear!
•  Help to find bugs!
•  Help to program faster
When to Refactor!
The Rule of Three
Three strikes and you refactor!
1.  You do something the first time!
2.  You do similar thing again with regret!
3.  On the third time – start refactoring!
!
When to Refactor!
•  When adding new functionality!
•  understanding the code!
•  prepare code for adding new functionality!
•  When fixing a bug!
•  error is a sign for refactoring!
•  Code reviews!
Problems with Refactoring!
Database!
•  difficult to change since tightly coupled to scheme!
•  existing data migration!
Changing Interface!
•  deprecate old interface!
•  just call new method in old method!
•  don’t publish premature interfaces!
When You Shouldn’t Refactor!
Low code quality!
•  easier rewrite than refactor!
•  code should work correctly before refactoring!
Deadline is too close!
•  postpone refactoring = technical debt!
Smelling Code!
Signs of low quality code!
Code Duplication!
•  The same code in two methods!
Extract Method!
•  The same code in two subclasses!
Extract Method + Pull Up Field / Method!
•  The same code in two different classes!
Extract Class!
Long Method!
•  Sections in method!
•  Wish to comment part of code !
•  Long loops and conditionals!
Extract Method!
Large Class!
•  To many methods!
•  To many fields!
Extract Class / Extract Subclass!
Long Parameter List!
•  Method can calculate parameter itself!
Replace Parameter with Method!
•  Parameters are fields of single object!
Preserve Whole Object!
•  Several related parameters!
Introduce Parameter Object!
Divergent Change!
•  Class is changed for different reasons!
Extract Class!
Shotgun Surgery!
•  Lots of little changes to lot of different classes!
Move Method / Move Field!
Feature Envy!
•  Method is interested in another class too much!
Move Method [+ Extract Method]!
Exceptions!
•  Strategy!
•  Visitor!
•  Data Access Layer!
Data Clumps!
•  Few data items together in lots of places!
Extract Class / Introduce Parameter Object!
Primitive Obsession!
•  Avoiding small classes and using primitives instead!
range, money, phone, array instead of object!
Replace Data Value with Object!
Extract Class / Introduce Parameter Object!
Switch Statements!
•  Switch statements all over the class!
Replace Type Code with Subclasses!
Replace Conditional with Polymorphism!
•  Few switch statements!
Replace Type Code with Strategy / State!
•  Null special cases!
Introduce Null Object!
Speculative Generality!
We need this functionality someday!
•  Unnecessary base class!
Collapse Hierarchy!
•  Unnecessary delegation!
Inline Class!
•  Strange abstract method name!
Rename Method!
Inappropriate Intimacy!
Classes too coupled!
•  Use fields and methods of each other!
Change Bidirectional Association with Unidirectional!
•  Have common interests!
Extract Class!
•  High coupling due to inheritance!
Replace Inheritance with Delegation!
Other Smells!
•  Lazy Class!
Inline Class!
•  Temporary Field!
Extract Class!
•  Message Chains getThis().getThat().getObject().method()!
Hide Delegate!
•  Refused Bequest!
Replace Inheritance with Delegation!
!
Comments!
Used like a deodorant
Indicators of bad code!
If you need a comment try to refactor!
•  Extract Method!
•  Rename Method!
•  Introduce Assertion!
!
Catalog of Refactorings!
Composing Methods!
Extract Method. Inline Method. Temporary Variables.
Replace Method with Method Object. !
Extract Method!
Turn the fragment of code into a method!
When
•  Method is too long!
•  Code needs an explanatory comment!
Why
•  Increase reusability!
•  Higher level methods become more readable!
•  Easier to override!
Extract Method!
public	
  void	
  PrintClient(Client	
  client)	
  {	
  
	
  	
  	
  	
  PrintBanner();	
  
	
  	
  	
  	
  //	
  print	
  client	
  details	
  
	
  	
  	
  	
  Console.Write("Name:	
  "	
  +	
  client.Name);	
  
	
  	
  	
  	
  Console.Write("Address:	
  "	
  +	
  client.Address);	
  
}	
  
public	
  void	
  PrintClient(Client	
  client)	
  {	
  
	
  	
  	
  	
  PrintBanner();	
  
	
  	
  	
  	
  PrintClientDetails(client);	
  
}	
  
private	
  void	
  PrintClientDetails(Client	
  client)	
  {	
  
	
  	
  	
  	
  Console.Write("Name:	
  "	
  +	
  client.Name);	
  
	
  	
  	
  	
  Console.Write("Address:	
  "	
  +	
  client.Address);	
  
}	
  
Inline Method!
Put the method body to callers and remove it!
When
•  Method body is as clear as its name!
•  Calling method is badly factored!
Why
•  Reduce redundant delegation!
•  Restructure calling method!
Inline Method!
public	
  int	
  GetRating()	
  {	
  
	
  	
  	
  	
  return	
  MoreThanFiveLateDeliveries()	
  ?	
  2	
  :	
  1;	
  
}	
  
private	
  bool	
  MoreThanFiveLateDeliveries()	
  {	
  
	
  	
  	
  	
  return	
  _numberOfLateDeliveries	
  >	
  5;	
  
}	
  
public	
  int	
  GetRating()	
  {	
  
	
  	
  	
  	
  return	
  (_numberOfLateDeliveries	
  >	
  5)	
  ?	
  2	
  :	
  1;	
  
}	
  
Replace Temp with Query!
Extract expression to a method and replace temp!
When
•  Temp holds an expression result for other methods!
•  Temp prevents from another refactoring!
Why
•  Cleaner code!
•  Shorter method!
•  The result is available to all methods!
Replace Temp with Query!
public	
  double	
  GetPrice()	
  {	
  
	
  	
  	
  	
  double	
  basePrice	
  =	
  _quantity	
  *	
  _itemPrice;	
  
	
  
	
  	
  	
  	
  return	
  (basePrice	
  >	
  1000)	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  ?	
  basePrice	
  *	
  0.95	
  
	
  	
  	
  	
  	
  	
  	
  	
  :	
  basePrice	
  *	
  0.98;	
  
}	
  
public	
  double	
  GetPrice()	
  {	
  
	
  	
  	
  	
  return	
  (BasePrice	
  >	
  1000)	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  ?	
  BasePrice	
  *	
  0.95	
  
	
  	
  	
  	
  	
  	
  	
  	
  :	
  BasePrice	
  *	
  0.98;	
  
}	
  
	
  
private	
  double	
  BasePrice	
  {	
  
	
  	
  	
  	
  get	
  {	
  return	
  _quantity	
  *	
  _itemPrice;	
  }	
  
}	
  
Introduce Explaining Variable!
Assign a part of expression to explaining variable!
When
•  Complex condition!
•  Complex algorithm!
Why
•  Improve code readability!
!
Introduce Explaining Variable!
if	
  ((platform.toUpperCase().indexOf("MAC")	
  >	
  -­‐1)	
  &&	
  
	
  	
  	
  	
  (browser.toUpperCase().indexOf("IE")	
  >	
  -­‐1)	
  &&	
  
	
  	
  	
  	
  isInitialized()	
  &&	
  resize	
  >	
  0)	
  {	
  
	
  	
  	
  	
  //	
  do	
  something	
  
}	
  
var	
  isMac	
  =	
  platform.toUpperCase().indexOf("MAC")	
  >	
  -­‐1;	
  
var	
  isIEBrowser	
  =	
  browser.toUpperCase().indexOf("IE")	
  >	
  -­‐1;	
  
var	
  isResized	
  =	
  resize	
  >	
  0;	
  
if	
  (isMac	
  &&	
  isIEBrowser	
  &&	
  isInitialized()	
  &&	
  isResized){	
  
	
  	
  	
  	
  //	
  do	
  something	
  
}	
  
Replace Method with Method Object!
Transform long method into object!
When
•  Long method with lots of temp variables!
Why
•  Improve readability!
•  Increase reusability!
!
Replace Method with Method Object!
class	
  Transaction	
  {	
  
	
  	
  	
  	
  public	
  double	
  BankFee()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  double	
  amount;	
  
	
  	
  	
  	
  	
  	
  	
  	
  double	
  price;	
  
	
  	
  	
  	
  	
  	
  	
  	
  double	
  tax;	
  
	
  	
  	
  	
  	
  	
  	
  	
  //	
  long	
  computations	
  
	
  	
  	
  	
  }	
  
Transaction
+BankFee()
BankFeeCalculator
-amount
-price
-tax
+Compute()
1
return new BankFeeCalculator(this).Compute();
Moving Features Between Objects!
Move Method. Move Field. Extract Class. Inline Class.
Hide Delegation.!
Move Method!
Move the method to the class that uses it most!
When
•  Method references another object too much!
•  Two classes are too coupled!
•  Class is overcomplicated!
Why
•  Lower coupling!
•  Simplify design!
!
Move Method!
class	
  Account	
  {	
  
	
  	
  private	
  AccountType	
  _type;	
  
	
  	
  public	
  double	
  BankCharge()	
  {	
  
	
  	
  	
  	
  double	
  result	
  =	
  FIXED_FEE;	
  
	
  	
  	
  	
  if(HasOverdraft())	
  
	
  	
  	
  	
  	
  	
  result	
  +=	
  OverdraftFee();	
  
	
  	
  	
  	
  return	
  result;	
  
	
  	
  }	
  
	
  	
  private	
  double	
  OverdraftFee()	
  {	
  
	
  	
  	
  	
  if(_type.IsPremium())	
  {	
  
	
  	
  	
  	
  	
  	
  //	
  premium	
  account	
  
	
  	
  	
  	
  }	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  //	
  standard	
  account	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
	
  
class	
  Account	
  {	
  
	
  	
  public	
  double	
  BankCharge()	
  {	
  
	
  	
  	
  	
  double	
  result	
  =	
  FIXED_FEE;	
  
	
  	
  	
  	
  if(HasOverdraft())	
  
	
  	
  	
  	
  	
  	
  result	
  +=	
  _type.OverdraftFee();	
  
	
  	
  	
  	
  return	
  result;	
  
	
  	
  }	
  
class	
  AccountType	
  {	
  
	
  	
  public	
  double	
  OverdraftFee()	
  {	
  
	
  	
  	
  	
  if(IsPremium())	
  {	
  
	
  	
  	
  	
  	
  	
  //	
  premium	
  account	
  
	
  	
  	
  	
  }	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  //	
  standard	
  account	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
Move Field!
Move the field to class that uses it most!
When
•  Another class uses a field more than its owner!
•  Performing Extract Class refactoring!
Why
•  Lower coupling!
•  Simplify design!
!
!
Move Field!
	
  
class	
  Account	
  {	
  
	
  	
  private	
  AccountType	
  _type;	
  
	
  	
  private	
  double	
  _interestRate;	
  
	
  	
  public	
  double	
  InterestRate	
  {	
  
	
  	
  	
  	
  get	
  {	
  return	
  _interestRate;	
  }	
  
	
  	
  }	
  
	
  	
  double	
  Interest(int	
  days)	
  {	
  
	
  	
  	
  	
  return	
  InterestRate	
  *	
  days/365;	
  
	
  	
  }	
  
	
  
	
  
class	
  Account	
  {	
  
	
  	
  double	
  Interest(int	
  days)	
  {	
  
	
  	
  	
  	
  return	
  _type.InterestRate	
  *	
  days/365;	
  
	
  	
  }	
  
class	
  AccountType	
  {	
  
	
  	
  private	
  double	
  _interestRate;	
  
	
  	
  public	
  double	
  InterestRate	
  {	
  
	
  	
  	
  	
  get	
  {	
  return	
  _interestRate;	
  }	
  
	
  	
  }	
  
Extract Class!
Create new class and move fields and methods!
When
•  Class is too big!
•  Single Responsibility Principle violation!
•  Data or methods dependent on each other!
Why
•  Simplify design!
!
!
Extract Class!
Person
-name
-officeAreaCode
-officeNumber
+OfficePhone()
Person
-name
+OfficePhone()
PhoneNumber
-areaCode
-number
+Phone()
-officePhone
Inline Class!
Move fields & methods from class and remove it!
When
•  Class is useless!
Why
•  Simplify design!
!
!
Inline Class!
Person
-name
-areaCode
-number
+Phone()
Person
-name
+Phone()
PhoneNumber
-areaCode
-number
+Phone()
-phone
Hide Delegate!
Create method on the server to hide the delegate!
When
•  object.getAnotherObject().method()!
Why
•  Lower coupling!
•  Strengthen encapsulation!
!
!
Hide Delegate!
Client
Person
+Department()
Department
+Manager()
Client
Person
+Manager()
Department
Organizing Data!
Self Encapsulate Field. Replacing Value with Object.
Replace Magic Number with Constant.
Replace Type Code with Subclasses/State/Strategy.!
Self Encapsulate Field!
Create and use getter and setter to access field!
When
•  Provide access to the field from outside!
•  Override property in a child class!
Why
•  Strengthen encapsulation!
•  Higher flexibility!
!
!
Self Encapsulate Field!
private	
  double	
  _interestRate;	
  
public	
  double	
  Interest(int	
  days)	
  {	
  
	
  	
  return	
  _interestRate	
  *	
  days/365;	
  
}	
  
private	
  double	
  _interestRate;	
  	
  	
  
public	
  double	
  InterestRate	
  {	
  
	
  	
  get	
  {	
  return	
  _interestRate;	
  }	
  
	
  	
  set	
  {	
  _interestRate	
  =	
  value;	
  }	
  
}	
  
public	
  double	
  Interest(int	
  days)	
  {	
  
	
  	
  return	
  InterestRate	
  *	
  days/365;	
  
}	
  	
  	
  
	
  
Replace Data Value with Object!
Turn the data item to an object!
When
•  Data item has dedicated methods!
•  Data items are used together in lots of places!
Why
•  Higher flexibility!
!
!
Replace Data Value with Object!
Order
-customer: string
Order
Customer
-name: string-customer
Replace Magic Number with Constant!
Replace magic value with named constant!
When
•  There is a magic value in the code!
Why
•  Improve code readability!
!
!
Replace Magic Number with Constant!
double	
  PotentialEnergy(double	
  mass,	
  double	
  height)	
  {	
  
	
  	
  return	
  mass	
  *	
  9.81	
  *	
  height;	
  
}	
  
static	
  const	
  double	
  GRAVITATIONAL_CONSTANT	
  =	
  9.81;	
  
double	
  PotentialEnergy(double	
  mass,	
  double	
  height)	
  {	
  
	
  	
  return	
  mass	
  *	
  GRAVITATIONAL_CONSTANT	
  *	
  height;	
  
}	
  
	
  
Replace Type Code with Subclasses!
Replace the type code with subclasses!
When
•  There is a type code influencing on class behavior!
Why
•  Increase extensibility!
!
!
Replace Type Code with Subclasses!
class	
  Employee	
  {	
  
	
  	
  private	
  EmployeeType	
  _type;	
  
	
  	
  Employee(EmployeeType	
  type)	
  {	
  
	
  	
  	
  	
  _type	
  =	
  type;	
  
	
  	
  }	
  
	
  	
  public	
  double	
  Bonus	
  {	
  
	
  	
  	
  	
  get	
  {	
  
	
  	
  	
  	
  	
  	
  switch(_type)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  case	
  EmployeeType.Engineer:	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  0.0;	
  
	
  	
  	
  	
  	
  	
  	
  	
  case	
  EmployeeType.Salesman:	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  return	
  0.25;	
  
	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
}
abstract	
  class	
  Employee	
  {	
  
	
  	
  abstract	
  EmployeeType	
  Type	
  {	
  get;	
  }	
  
	
  	
  abstract	
  double	
  Bonus	
  {	
  get;	
  }	
  
}	
  
class	
  Engineer:	
  Employee	
  {	
  
	
  	
  public	
  override	
  EmployeeType	
  Type	
  {	
  
	
  	
  	
  	
  get	
  {	
  	
  
	
  	
  	
  	
  	
  	
  return	
  EmployeeType.Engineer;	
  	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
	
  	
  public	
  override	
  double	
  Bonus	
  {	
  
	
  	
  	
  	
  get	
  {	
  	
  
	
  	
  	
  	
  	
  	
  return	
  0.0;	
  	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
}	
  
Replace Type Code with State/Strategy!
Replace the type code with state/strategy classes!
When
•  There is a type code influencing on class behavior!
•  Type code may change during object life!
Why
•  Increase extensibility!
!
!
Replace Type Code with State/Strategy!
Employee
EmployeeType
<< enum >>
EmployeeType
Salesman
Engineer
-type
Employee
Salesman Engineer
-type
Simplifying Conditional Expressions!
Decompose Conditional Expression.
Replace Conditional with Polymorphism.
Guard Clauses. Introduce Null Object.!
Decompose Conditional!
Extract methods from condition and branches!
When
•  Condition with complex expression and branches!
Why
•  Improve code readability!
!
Decompose Conditional!
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);	
  
Replace Nested Conditional with Guard Clauses!
Use guard clauses for all special cases!
When
•  Conditional expression with special case branch!
Why
•  Improve code readability!
!
Replace Nested Conditional with Guard Clauses!
double	
  PayAmount()	
  {	
  
	
  	
  double	
  result;	
  
	
  	
  if(_isDead)	
  
	
  	
  	
  	
  result	
  =	
  DeadAmount();	
  
	
  	
  else	
  {	
  
	
  	
  	
  	
  if(_isSeparated)	
  	
  
	
  	
  	
  	
  	
  	
  result	
  =	
  SeparatedAmount();	
  
	
  	
  	
  	
  else	
  {	
  
	
  	
  	
  	
  	
  	
  if(_isRetired)	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  result	
  =	
  RetiredAmount();	
  
	
  	
  	
  	
  	
  	
  else	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  result	
  =	
  NormalAmount();	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
	
  	
  return	
  result;	
  
}	
  
	
  
double	
  PayAmount()	
  {	
  
	
  	
  if(_isDead)	
  	
  
	
  	
  	
  	
  return	
  DeadAmount();	
  
	
  	
  if(_isSeparated)	
  	
  
	
  	
  	
  	
  return	
  SeparatedAmount();	
  
	
  	
  if(_isRetired)	
  	
  
	
  	
  	
  	
  return	
  RetiredAmount();	
  
	
  
	
  	
  return	
  NormalAmount();	
  
}	
  
Replace Conditional with Polymorphism!
Move every condition branch to subclass method!
When
•  There are conditions depending on object type!
Why
•  Increase extensibility!
•  Improve code readability!
!
!
Replace Conditional with Polymorphism!
class	
  Employee	
  {	
  
	
  	
  public	
  double	
  PayAmount()	
  {	
  
	
  	
  	
  	
  switch	
  (_type)	
  {	
  
	
  	
  	
  	
  	
  	
  case	
  EmployeeType.Engineer:	
  return	
  _salary;	
  
	
  	
  	
  	
  	
  	
  case	
  EmployeeType.Salesman:	
  return	
  _salary	
  +	
  _commission;	
  
	
  	
  	
  	
  	
  	
  case	
  EmployeeType.Manager:	
  return	
  _salary	
  +	
  _bonus;	
  
	
  	
  	
  	
  	
  	
  default:	
  throw	
  new	
  WrongEmployeeTypeException();	
  	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
Employee
+PayAmount()
Engineer
+PayAmount()
Salesman
+PayAmount()
Manager
+PayAmount()
Introduce Null Object!
Replace null value with special class!
When
•  There are lots of null checks!
Why
•  Reduce conditionals!
!
!
Introduce Null Object!
if(employee	
  ==	
  null)	
  
	
  	
  name	
  =	
  NAME_PLACEHOLDER;	
  
else	
  	
  
	
  	
  name	
  =	
  employee.FullName;	
  
Employee
+FullName()
NullEmployee
+FullName()
Making Method Calls Simpler!
Rename Method. Separate Query from Modifier.
Preserve Whole Object. Introduce Parameter Object.
Error Handling Refactorings.!
Rename Method!
Change method name!
When
•  Method name doesn't show its intention !
Why
•  Improve code readability!
Rename Method!
SecurityPrice
+LowerLimitExceed()
SecurityPrice
+IsLowerLimitExceeded()
Separate Query from Modifier!
Create methods for query and for modification!
When
•  Method returning value modifies object state!
Why
•  Simplify interface!
Separate Query from Modifier!
public	
  List<Employee>	
  FindRetired(List<Employee>	
  employees)	
  {	
  
	
  	
  var	
  result	
  =	
  new	
  List<Employee>();	
  
	
  	
  foreach(var	
  emp	
  in	
  employees)	
  {	
  
	
  	
  	
  	
  if(emp.IsRetired)	
  {	
  
	
  	
  	
  	
  	
  	
  AddBonus(emp);	
  
	
  	
  	
  	
  	
  	
  result.Add(emp);	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
	
  	
  return	
  result;	
  
}	
  
public	
  List<Employee>	
  FindRetired(List<Employee>	
  employees)	
  {	
  
	
  	
  return	
  employees.Where(emp	
  =>	
  emp.IsRetired).ToList();	
  	
  	
  
}	
  
public	
  void	
  AddBonusToRetired(List<Employee>	
  employees)	
  {	
  
	
  	
  foreach(var	
  emp	
  in	
  employees)	
  {	
  
	
  	
  	
  	
  if(emp.IsRetired)	
  
	
  	
  	
  	
  	
  	
  AddBonus(emp);	
  
	
  	
  }	
  
}	
  
	
  
Preserve Whole Object!
Send the whole object to the method!
When
•  Method has several object field values as params!
Why
•  Simplify interface!
!
Preserve Whole Object!
DateTime	
  start	
  =	
  Period.Start;	
  
DateTime	
  end	
  =	
  Period.End;	
  
List<Event>	
  events	
  =	
  schedule.FindEvents(start,	
  end);	
  
	
  
	
  
	
  
List<Event>	
  events	
  =	
  schedule.FindEvents(Period);	
  
Introduce Parameter Object!
Replace method parameters with an object!
When
•  Method accepts several related parameters!
Why
•  Simplify interface!
Introduce Parameter Object!
Schedule
+FindEvents(DateTime start, DateTime end)
Schedule
+FindEvents(Period period)
Replace Error Code with Exception!
Throw exception instead of returning error code!
When
•  Method returns error code!
Why
•  Simplify interface!
Replace Error Code with Exception!
int	
  Withdraw(int	
  amount)	
  {	
  
	
  	
  if	
  (amount	
  >	
  _balance)	
  {	
  
	
  	
  	
  	
  return	
  -­‐1;	
  
	
  	
  }	
  
	
  	
  else	
  {	
  
	
  	
  	
  	
  _balance	
  -­‐=	
  amount;	
  
	
  	
  	
  	
  return	
  0;	
  
	
  	
  }	
  
}	
  
void	
  Withdraw(int	
  amount)	
  {	
  
	
  	
  if	
  (amount	
  >	
  _balance)	
  	
  
	
  	
  	
  	
  throw	
  new	
  BalanceException();	
  
	
  
	
  	
  _balance	
  -­‐=	
  amount;	
  
}	
  
Replace Exception with Test!
Put conditional instead of throwing exception!
When
•  Exception is used non-exceptional case!
Why
•  Improve code readability!
Replace Exception with Test!
public	
  double	
  ValueForPeriod(int	
  periodIndex)	
  {	
  
	
  	
  try	
  {	
  
	
  	
  	
  	
  return	
  _values[periodIndex];	
  
	
  	
  }	
  
	
  	
  catch	
  (IndexOutOfRangeException	
  e)	
  {	
  
	
  	
  	
  	
  return	
  0;	
  
	
  	
  }	
  
}	
  
public	
  double	
  ValueForPeriod(int	
  periodIndex)	
  {	
  
	
  	
  if	
  (periodIndex	
  >=	
  _values.length)	
  	
  
	
  return	
  0;	
  
	
  	
  return	
  _values[periodIndex];	
  
}	
  
Generalization Refactorings!
Pull Up and Push Down Method/Field.
Replace Inheritance with Delegation.
Extract Subclass/Superclass. !
Pull Up Field/Method!
Move method/field into the superclass!
When
•  The same method/field is in several child classes!
Why
•  Remove duplication!
Pull Up Field/Method!
Salesman
+name
Engineer
+name
Employee
+name
Salesman Engineer
Employee
Push Down Field/Method!
Move method/field into the subclass!
When
•  Superclass has method/field used only in one child!
Why
•  Simplify design!
Push Down Field/Method!
Salesman
+ComissionRate
Engineer
Employee
+ComissionRate
Salesman Engineer
Employee
Extract Subclass!
Create subclass for subset of features!
When
•  Subset of features used only in some instances!
Why
•  Improve code readability!
!
Extract Subclass!
Event
+Start: DateTime
+Duration: TimeSpan
+Repeat: EventPeriodicity
Event
+Start: DateTime
+Duration: TimeSpan
PeriodicEvent
+Repeat: EventPeriodicity
Extract Superclass!
Create superclass and move common features!
When
•  Several classes have the same subset of features!
Why
•  Remove duplication!
!
Extract Superclass!
AccountTransaction
+Change: decimal
+Saldo: decimal
+TradeDate: DateTime
Transaction
+Change: decimal
+TradeDate: DateTime
Order
+Amount: int
+Price: decimal
+Change: decimal
+Security: Security
+TradeDate: DateTime
AccountTransaction
+Saldo: decimal
Order
+Amount: int
+Price: decimal
+Security: Security
Replace Inheritance with Delegation!
Put superclass to a field and use delegation!
When
•  Unable to say “subclass is a superclass”!
•  Subclass implements superclass interface partially!
Why
•  Simplify design!
!
Replace Inheritance with Delegation!
Array
+Insert(T item)
+IsEmpty()
Stack
+Push(T Item)
+Pop(): T
Array
+Insert(T item)
+IsEmpty()
Stack
+Push(T Item)
+Pop(): T
+IsEmpty()
-array
return _array.IsEmpty();
Architectural Refactorings!
Tease Apart Hierarchies. Extract Hierarchy.
Convert Procedural Design to Objects.
Separate Domain from Presentation. !
Tease Apart Inheritance!
Create two hierarchies using one another!
When
•  The inheritance hierarchy has two responsibilities!
Why
•  Simplify design!
!
Tease Apart Inheritance!
Security
Bond
Security
BondAction
SecurityOperation
SellingDelivery
1
*
DeliveredBondSoldAction
Action
Extract Hierarchy!
Create hierarchy with subclass per special case!
When
•  The single class overwhelmed with conditionals!
Why
•  Improve code readability!
•  Improve architecture!
!
Extract Hierarchy!
Logger
+SendEmail(message)
+WriteToFile(message)
+WriteToSystemLog(message)
Logger
SystemLogger FileLogger EmailLogger
Convert Procedural Design to Objects!
Turn data into objects and behavior into methods!
When
•  The classes with long methods but without fields!
•  The classes with fields but without methods!
Why
•  Improve code readability!
•  Improve architecture!
!
Convert Procedural Design to Objects!
OrderCalculator
+CalculatePrice(order)
+CalculateTaxes(order)
OrderOrderLine
Order
+Price()
+Taxes()
OrderLine
+Price()
+Taxes()
1 *
Separate Domain from Presentation !
Create domain logic classes separated from ui!
When
•  UI logic is mixed with domain logic!
Why
•  Improve code readability!
•  Improve architecture!
!
Separate Domain from Presentation!
ClientPage
(business logic embedded)
ClientClientPage
1
Thank you!!
Your questions, please!!
ARTEM TABALIN!
References!
•  Martin Fowler Refactoring!
•  Robert C. Martin Clean Code!
•  Steve McConnell Code Complete!!

More Related Content

What's hot

Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerIgor Crvenov
 
Introduction to CICD
Introduction to CICDIntroduction to CICD
Introduction to CICDKnoldus Inc.
 
Devops Devops Devops
Devops Devops DevopsDevops Devops Devops
Devops Devops DevopsKris Buytaert
 
Modern UI Development With Node.js
Modern UI Development With Node.jsModern UI Development With Node.js
Modern UI Development With Node.jsRyan Anklam
 
CSharp Presentation
CSharp PresentationCSharp Presentation
CSharp PresentationVishwa Mohan
 
SOLID Design Principles
SOLID Design PrinciplesSOLID Design Principles
SOLID Design PrinciplesAndreas Enbohm
 
Code Smells and Its type (With Example)
Code Smells and Its type (With Example)Code Smells and Its type (With Example)
Code Smells and Its type (With Example)Anshul Vinayak
 
CI/CD Overview
CI/CD OverviewCI/CD Overview
CI/CD OverviewAn Nguyen
 
Oops concepts || Object Oriented Programming Concepts in Java
Oops concepts || Object Oriented Programming Concepts in JavaOops concepts || Object Oriented Programming Concepts in Java
Oops concepts || Object Oriented Programming Concepts in JavaMadishetty Prathibha
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smellsPaul Nguyen
 
oops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaoops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaCPD INDIA
 

What's hot (20)

Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
Introducing DevOps
Introducing DevOpsIntroducing DevOps
Introducing DevOps
 
Introduction to CICD
Introduction to CICDIntroduction to CICD
Introduction to CICD
 
Refactoring
RefactoringRefactoring
Refactoring
 
Introduction to c#
Introduction to c#Introduction to c#
Introduction to c#
 
Devops Devops Devops
Devops Devops DevopsDevops Devops Devops
Devops Devops Devops
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Code smell overview
Code smell overviewCode smell overview
Code smell overview
 
Modern UI Development With Node.js
Modern UI Development With Node.jsModern UI Development With Node.js
Modern UI Development With Node.js
 
DevOps and Tools
DevOps and ToolsDevOps and Tools
DevOps and Tools
 
CSharp Presentation
CSharp PresentationCSharp Presentation
CSharp Presentation
 
SOLID Design Principles
SOLID Design PrinciplesSOLID Design Principles
SOLID Design Principles
 
3. ch 2-process model
3. ch 2-process model3. ch 2-process model
3. ch 2-process model
 
Introduction to devops
Introduction to devopsIntroduction to devops
Introduction to devops
 
Code Smells and Its type (With Example)
Code Smells and Its type (With Example)Code Smells and Its type (With Example)
Code Smells and Its type (With Example)
 
CI/CD Overview
CI/CD OverviewCI/CD Overview
CI/CD Overview
 
Oops concepts || Object Oriented Programming Concepts in Java
Oops concepts || Object Oriented Programming Concepts in JavaOops concepts || Object Oriented Programming Concepts in Java
Oops concepts || Object Oriented Programming Concepts in Java
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
 
oops concept in java | object oriented programming in java
oops concept in java | object oriented programming in javaoops concept in java | object oriented programming in java
oops concept in java | object oriented programming in java
 

Viewers also liked

Refactoring - An Introduction
Refactoring - An IntroductionRefactoring - An Introduction
Refactoring - An IntroductionGiorgio Vespucci
 
Refactoring 101
Refactoring 101Refactoring 101
Refactoring 101Adam Culp
 
The Decorator Pattern
The Decorator PatternThe Decorator Pattern
The Decorator PatternAkshat Vig
 
Introduction to Design Pattern
Introduction to Design  PatternIntroduction to Design  Pattern
Introduction to Design PatternSanae BEKKAR
 
Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材teddysoft
 
Design Patterns Illustrated
Design Patterns IllustratedDesign Patterns Illustrated
Design Patterns IllustratedHerman Peeren
 
Design Patterns - 01 Introduction and Decorator Pattern
Design Patterns - 01 Introduction and Decorator PatternDesign Patterns - 01 Introduction and Decorator Pattern
Design Patterns - 01 Introduction and Decorator Patterneprafulla
 
Design Patterns
Design PatternsDesign Patterns
Design Patternssoms_1
 

Viewers also liked (10)

Refactoring - An Introduction
Refactoring - An IntroductionRefactoring - An Introduction
Refactoring - An Introduction
 
Refactoring 101
Refactoring 101Refactoring 101
Refactoring 101
 
The Decorator Pattern
The Decorator PatternThe Decorator Pattern
The Decorator Pattern
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Code Refactoring
Code RefactoringCode Refactoring
Code Refactoring
 
Introduction to Design Pattern
Introduction to Design  PatternIntroduction to Design  Pattern
Introduction to Design Pattern
 
Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材Design Patterns這樣學就會了:入門班 Day1 教材
Design Patterns這樣學就會了:入門班 Day1 教材
 
Design Patterns Illustrated
Design Patterns IllustratedDesign Patterns Illustrated
Design Patterns Illustrated
 
Design Patterns - 01 Introduction and Decorator Pattern
Design Patterns - 01 Introduction and Decorator PatternDesign Patterns - 01 Introduction and Decorator Pattern
Design Patterns - 01 Introduction and Decorator Pattern
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 

Similar to Refactoring

Learning to run
Learning to runLearning to run
Learning to rundominion
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindiaComplaints
 
Introduction to JavaScript design patterns
Introduction to JavaScript design patternsIntroduction to JavaScript design patterns
Introduction to JavaScript design patternsJeremy Duvall
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018Mike Harris
 
Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to DomainJeremy Cook
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Mike Schinkel
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin GeneratorJohn Cleveley
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
PHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginnersPHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginnersMohammed Mushtaq Ahmed
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Miguel Gallardo
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
Learning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersLearning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersKathy Brown
 
Dutch PHP Conference 2015 - The quest for global design principles
Dutch PHP Conference 2015 - The quest for global design principlesDutch PHP Conference 2015 - The quest for global design principles
Dutch PHP Conference 2015 - The quest for global design principlesMatthias Noback
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami
 

Similar to Refactoring (20)

Learning to run
Learning to runLearning to run
Learning to run
 
Synapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephpSynapseindia reviews sharing intro cakephp
Synapseindia reviews sharing intro cakephp
 
Introduction to JavaScript design patterns
Introduction to JavaScript design patternsIntroduction to JavaScript design patterns
Introduction to JavaScript design patterns
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
 
Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to Domain
 
Php
PhpPhp
Php
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
Perfect Code
Perfect CodePerfect Code
Perfect Code
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
 
Working With The Symfony Admin Generator
Working With The Symfony Admin GeneratorWorking With The Symfony Admin Generator
Working With The Symfony Admin Generator
 
JS Essence
JS EssenceJS Essence
JS Essence
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
PHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginnersPHP complete reference with database concepts for beginners
PHP complete reference with database concepts for beginners
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Learning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersLearning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client Developers
 
Dutch PHP Conference 2015 - The quest for global design principles
Dutch PHP Conference 2015 - The quest for global design principlesDutch PHP Conference 2015 - The quest for global design principles
Dutch PHP Conference 2015 - The quest for global design principles
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
 

Recently uploaded

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineeringssuserb3a23b
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 

Recently uploaded (20)

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineering
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 

Refactoring

  • 1. Refactoring! How to improve your code! ARTEM TABALIN!
  • 2. What is refactoring?! Definition. Goals. When to Refactor. Pitfalls.!
  • 3. What is Refactoring?! ! “Refactoring is a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.”! - Martin Fowler! Is it just cleaning up code?! The technique of cleaning up code in more organized and controlled way!
  • 4. The Two Hats! Two distinct activities! 1.  adding functions 2.  refactoring! These two activities should NOT take place at the same time!
  • 5. Goals! •  Prevent code quality reduction! •  Make code clear! •  Help to find bugs! •  Help to program faster
  • 6. When to Refactor! The Rule of Three Three strikes and you refactor! 1.  You do something the first time! 2.  You do similar thing again with regret! 3.  On the third time – start refactoring! !
  • 7. When to Refactor! •  When adding new functionality! •  understanding the code! •  prepare code for adding new functionality! •  When fixing a bug! •  error is a sign for refactoring! •  Code reviews!
  • 8. Problems with Refactoring! Database! •  difficult to change since tightly coupled to scheme! •  existing data migration! Changing Interface! •  deprecate old interface! •  just call new method in old method! •  don’t publish premature interfaces!
  • 9. When You Shouldn’t Refactor! Low code quality! •  easier rewrite than refactor! •  code should work correctly before refactoring! Deadline is too close! •  postpone refactoring = technical debt!
  • 10. Smelling Code! Signs of low quality code!
  • 11. Code Duplication! •  The same code in two methods! Extract Method! •  The same code in two subclasses! Extract Method + Pull Up Field / Method! •  The same code in two different classes! Extract Class!
  • 12. Long Method! •  Sections in method! •  Wish to comment part of code ! •  Long loops and conditionals! Extract Method!
  • 13. Large Class! •  To many methods! •  To many fields! Extract Class / Extract Subclass!
  • 14. Long Parameter List! •  Method can calculate parameter itself! Replace Parameter with Method! •  Parameters are fields of single object! Preserve Whole Object! •  Several related parameters! Introduce Parameter Object!
  • 15. Divergent Change! •  Class is changed for different reasons! Extract Class!
  • 16. Shotgun Surgery! •  Lots of little changes to lot of different classes! Move Method / Move Field!
  • 17. Feature Envy! •  Method is interested in another class too much! Move Method [+ Extract Method]! Exceptions! •  Strategy! •  Visitor! •  Data Access Layer!
  • 18. Data Clumps! •  Few data items together in lots of places! Extract Class / Introduce Parameter Object!
  • 19. Primitive Obsession! •  Avoiding small classes and using primitives instead! range, money, phone, array instead of object! Replace Data Value with Object! Extract Class / Introduce Parameter Object!
  • 20. Switch Statements! •  Switch statements all over the class! Replace Type Code with Subclasses! Replace Conditional with Polymorphism! •  Few switch statements! Replace Type Code with Strategy / State! •  Null special cases! Introduce Null Object!
  • 21. Speculative Generality! We need this functionality someday! •  Unnecessary base class! Collapse Hierarchy! •  Unnecessary delegation! Inline Class! •  Strange abstract method name! Rename Method!
  • 22. Inappropriate Intimacy! Classes too coupled! •  Use fields and methods of each other! Change Bidirectional Association with Unidirectional! •  Have common interests! Extract Class! •  High coupling due to inheritance! Replace Inheritance with Delegation!
  • 23. Other Smells! •  Lazy Class! Inline Class! •  Temporary Field! Extract Class! •  Message Chains getThis().getThat().getObject().method()! Hide Delegate! •  Refused Bequest! Replace Inheritance with Delegation! !
  • 24. Comments! Used like a deodorant Indicators of bad code! If you need a comment try to refactor! •  Extract Method! •  Rename Method! •  Introduce Assertion! !
  • 26. Composing Methods! Extract Method. Inline Method. Temporary Variables. Replace Method with Method Object. !
  • 27. Extract Method! Turn the fragment of code into a method! When •  Method is too long! •  Code needs an explanatory comment! Why •  Increase reusability! •  Higher level methods become more readable! •  Easier to override!
  • 28. Extract Method! public  void  PrintClient(Client  client)  {          PrintBanner();          //  print  client  details          Console.Write("Name:  "  +  client.Name);          Console.Write("Address:  "  +  client.Address);   }   public  void  PrintClient(Client  client)  {          PrintBanner();          PrintClientDetails(client);   }   private  void  PrintClientDetails(Client  client)  {          Console.Write("Name:  "  +  client.Name);          Console.Write("Address:  "  +  client.Address);   }  
  • 29. Inline Method! Put the method body to callers and remove it! When •  Method body is as clear as its name! •  Calling method is badly factored! Why •  Reduce redundant delegation! •  Restructure calling method!
  • 30. Inline Method! public  int  GetRating()  {          return  MoreThanFiveLateDeliveries()  ?  2  :  1;   }   private  bool  MoreThanFiveLateDeliveries()  {          return  _numberOfLateDeliveries  >  5;   }   public  int  GetRating()  {          return  (_numberOfLateDeliveries  >  5)  ?  2  :  1;   }  
  • 31. Replace Temp with Query! Extract expression to a method and replace temp! When •  Temp holds an expression result for other methods! •  Temp prevents from another refactoring! Why •  Cleaner code! •  Shorter method! •  The result is available to all methods!
  • 32. Replace Temp with Query! public  double  GetPrice()  {          double  basePrice  =  _quantity  *  _itemPrice;            return  (basePrice  >  1000)                    ?  basePrice  *  0.95                  :  basePrice  *  0.98;   }   public  double  GetPrice()  {          return  (BasePrice  >  1000)                    ?  BasePrice  *  0.95                  :  BasePrice  *  0.98;   }     private  double  BasePrice  {          get  {  return  _quantity  *  _itemPrice;  }   }  
  • 33. Introduce Explaining Variable! Assign a part of expression to explaining variable! When •  Complex condition! •  Complex algorithm! Why •  Improve code readability! !
  • 34. Introduce Explaining Variable! if  ((platform.toUpperCase().indexOf("MAC")  >  -­‐1)  &&          (browser.toUpperCase().indexOf("IE")  >  -­‐1)  &&          isInitialized()  &&  resize  >  0)  {          //  do  something   }   var  isMac  =  platform.toUpperCase().indexOf("MAC")  >  -­‐1;   var  isIEBrowser  =  browser.toUpperCase().indexOf("IE")  >  -­‐1;   var  isResized  =  resize  >  0;   if  (isMac  &&  isIEBrowser  &&  isInitialized()  &&  isResized){          //  do  something   }  
  • 35. Replace Method with Method Object! Transform long method into object! When •  Long method with lots of temp variables! Why •  Improve readability! •  Increase reusability! !
  • 36. Replace Method with Method Object! class  Transaction  {          public  double  BankFee()  {                  double  amount;                  double  price;                  double  tax;                  //  long  computations          }   Transaction +BankFee() BankFeeCalculator -amount -price -tax +Compute() 1 return new BankFeeCalculator(this).Compute();
  • 37. Moving Features Between Objects! Move Method. Move Field. Extract Class. Inline Class. Hide Delegation.!
  • 38. Move Method! Move the method to the class that uses it most! When •  Method references another object too much! •  Two classes are too coupled! •  Class is overcomplicated! Why •  Lower coupling! •  Simplify design! !
  • 39. Move Method! class  Account  {      private  AccountType  _type;      public  double  BankCharge()  {          double  result  =  FIXED_FEE;          if(HasOverdraft())              result  +=  OverdraftFee();          return  result;      }      private  double  OverdraftFee()  {          if(_type.IsPremium())  {              //  premium  account          }  else  {              //  standard  account          }      }     class  Account  {      public  double  BankCharge()  {          double  result  =  FIXED_FEE;          if(HasOverdraft())              result  +=  _type.OverdraftFee();          return  result;      }   class  AccountType  {      public  double  OverdraftFee()  {          if(IsPremium())  {              //  premium  account          }  else  {              //  standard  account          }      }  
  • 40. Move Field! Move the field to class that uses it most! When •  Another class uses a field more than its owner! •  Performing Extract Class refactoring! Why •  Lower coupling! •  Simplify design! ! !
  • 41. Move Field!   class  Account  {      private  AccountType  _type;      private  double  _interestRate;      public  double  InterestRate  {          get  {  return  _interestRate;  }      }      double  Interest(int  days)  {          return  InterestRate  *  days/365;      }       class  Account  {      double  Interest(int  days)  {          return  _type.InterestRate  *  days/365;      }   class  AccountType  {      private  double  _interestRate;      public  double  InterestRate  {          get  {  return  _interestRate;  }      }  
  • 42. Extract Class! Create new class and move fields and methods! When •  Class is too big! •  Single Responsibility Principle violation! •  Data or methods dependent on each other! Why •  Simplify design! ! !
  • 44. Inline Class! Move fields & methods from class and remove it! When •  Class is useless! Why •  Simplify design! ! !
  • 46. Hide Delegate! Create method on the server to hide the delegate! When •  object.getAnotherObject().method()! Why •  Lower coupling! •  Strengthen encapsulation! ! !
  • 48. Organizing Data! Self Encapsulate Field. Replacing Value with Object. Replace Magic Number with Constant. Replace Type Code with Subclasses/State/Strategy.!
  • 49. Self Encapsulate Field! Create and use getter and setter to access field! When •  Provide access to the field from outside! •  Override property in a child class! Why •  Strengthen encapsulation! •  Higher flexibility! ! !
  • 50. Self Encapsulate Field! private  double  _interestRate;   public  double  Interest(int  days)  {      return  _interestRate  *  days/365;   }   private  double  _interestRate;       public  double  InterestRate  {      get  {  return  _interestRate;  }      set  {  _interestRate  =  value;  }   }   public  double  Interest(int  days)  {      return  InterestRate  *  days/365;   }        
  • 51. Replace Data Value with Object! Turn the data item to an object! When •  Data item has dedicated methods! •  Data items are used together in lots of places! Why •  Higher flexibility! ! !
  • 52. Replace Data Value with Object! Order -customer: string Order Customer -name: string-customer
  • 53. Replace Magic Number with Constant! Replace magic value with named constant! When •  There is a magic value in the code! Why •  Improve code readability! ! !
  • 54. Replace Magic Number with Constant! double  PotentialEnergy(double  mass,  double  height)  {      return  mass  *  9.81  *  height;   }   static  const  double  GRAVITATIONAL_CONSTANT  =  9.81;   double  PotentialEnergy(double  mass,  double  height)  {      return  mass  *  GRAVITATIONAL_CONSTANT  *  height;   }    
  • 55. Replace Type Code with Subclasses! Replace the type code with subclasses! When •  There is a type code influencing on class behavior! Why •  Increase extensibility! ! !
  • 56. Replace Type Code with Subclasses! class  Employee  {      private  EmployeeType  _type;      Employee(EmployeeType  type)  {          _type  =  type;      }      public  double  Bonus  {          get  {              switch(_type)  {                  case  EmployeeType.Engineer:                      return  0.0;                  case  EmployeeType.Salesman:                      return  0.25;              }          }      }   } abstract  class  Employee  {      abstract  EmployeeType  Type  {  get;  }      abstract  double  Bonus  {  get;  }   }   class  Engineer:  Employee  {      public  override  EmployeeType  Type  {          get  {                return  EmployeeType.Engineer;            }      }      public  override  double  Bonus  {          get  {                return  0.0;            }      }   }  
  • 57. Replace Type Code with State/Strategy! Replace the type code with state/strategy classes! When •  There is a type code influencing on class behavior! •  Type code may change during object life! Why •  Increase extensibility! ! !
  • 58. Replace Type Code with State/Strategy! Employee EmployeeType << enum >> EmployeeType Salesman Engineer -type Employee Salesman Engineer -type
  • 59. Simplifying Conditional Expressions! Decompose Conditional Expression. Replace Conditional with Polymorphism. Guard Clauses. Introduce Null Object.!
  • 60. Decompose Conditional! Extract methods from condition and branches! When •  Condition with complex expression and branches! Why •  Improve code readability! !
  • 61. Decompose Conditional! 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);  
  • 62. Replace Nested Conditional with Guard Clauses! Use guard clauses for all special cases! When •  Conditional expression with special case branch! Why •  Improve code readability! !
  • 63. Replace Nested Conditional with Guard Clauses! double  PayAmount()  {      double  result;      if(_isDead)          result  =  DeadAmount();      else  {          if(_isSeparated)                result  =  SeparatedAmount();          else  {              if(_isRetired)                    result  =  RetiredAmount();              else                    result  =  NormalAmount();          }      }      return  result;   }     double  PayAmount()  {      if(_isDead)            return  DeadAmount();      if(_isSeparated)            return  SeparatedAmount();      if(_isRetired)            return  RetiredAmount();        return  NormalAmount();   }  
  • 64. Replace Conditional with Polymorphism! Move every condition branch to subclass method! When •  There are conditions depending on object type! Why •  Increase extensibility! •  Improve code readability! ! !
  • 65. Replace Conditional with Polymorphism! class  Employee  {      public  double  PayAmount()  {          switch  (_type)  {              case  EmployeeType.Engineer:  return  _salary;              case  EmployeeType.Salesman:  return  _salary  +  _commission;              case  EmployeeType.Manager:  return  _salary  +  _bonus;              default:  throw  new  WrongEmployeeTypeException();            }      }   Employee +PayAmount() Engineer +PayAmount() Salesman +PayAmount() Manager +PayAmount()
  • 66. Introduce Null Object! Replace null value with special class! When •  There are lots of null checks! Why •  Reduce conditionals! ! !
  • 67. Introduce Null Object! if(employee  ==  null)      name  =  NAME_PLACEHOLDER;   else        name  =  employee.FullName;   Employee +FullName() NullEmployee +FullName()
  • 68. Making Method Calls Simpler! Rename Method. Separate Query from Modifier. Preserve Whole Object. Introduce Parameter Object. Error Handling Refactorings.!
  • 69. Rename Method! Change method name! When •  Method name doesn't show its intention ! Why •  Improve code readability!
  • 71. Separate Query from Modifier! Create methods for query and for modification! When •  Method returning value modifies object state! Why •  Simplify interface!
  • 72. Separate Query from Modifier! public  List<Employee>  FindRetired(List<Employee>  employees)  {      var  result  =  new  List<Employee>();      foreach(var  emp  in  employees)  {          if(emp.IsRetired)  {              AddBonus(emp);              result.Add(emp);          }      }      return  result;   }   public  List<Employee>  FindRetired(List<Employee>  employees)  {      return  employees.Where(emp  =>  emp.IsRetired).ToList();       }   public  void  AddBonusToRetired(List<Employee>  employees)  {      foreach(var  emp  in  employees)  {          if(emp.IsRetired)              AddBonus(emp);      }   }    
  • 73. Preserve Whole Object! Send the whole object to the method! When •  Method has several object field values as params! Why •  Simplify interface! !
  • 74. Preserve Whole Object! DateTime  start  =  Period.Start;   DateTime  end  =  Period.End;   List<Event>  events  =  schedule.FindEvents(start,  end);         List<Event>  events  =  schedule.FindEvents(Period);  
  • 75. Introduce Parameter Object! Replace method parameters with an object! When •  Method accepts several related parameters! Why •  Simplify interface!
  • 76. Introduce Parameter Object! Schedule +FindEvents(DateTime start, DateTime end) Schedule +FindEvents(Period period)
  • 77. Replace Error Code with Exception! Throw exception instead of returning error code! When •  Method returns error code! Why •  Simplify interface!
  • 78. Replace Error Code with Exception! int  Withdraw(int  amount)  {      if  (amount  >  _balance)  {          return  -­‐1;      }      else  {          _balance  -­‐=  amount;          return  0;      }   }   void  Withdraw(int  amount)  {      if  (amount  >  _balance)            throw  new  BalanceException();        _balance  -­‐=  amount;   }  
  • 79. Replace Exception with Test! Put conditional instead of throwing exception! When •  Exception is used non-exceptional case! Why •  Improve code readability!
  • 80. Replace Exception with Test! public  double  ValueForPeriod(int  periodIndex)  {      try  {          return  _values[periodIndex];      }      catch  (IndexOutOfRangeException  e)  {          return  0;      }   }   public  double  ValueForPeriod(int  periodIndex)  {      if  (periodIndex  >=  _values.length)      return  0;      return  _values[periodIndex];   }  
  • 81. Generalization Refactorings! Pull Up and Push Down Method/Field. Replace Inheritance with Delegation. Extract Subclass/Superclass. !
  • 82. Pull Up Field/Method! Move method/field into the superclass! When •  The same method/field is in several child classes! Why •  Remove duplication!
  • 84. Push Down Field/Method! Move method/field into the subclass! When •  Superclass has method/field used only in one child! Why •  Simplify design!
  • 86. Extract Subclass! Create subclass for subset of features! When •  Subset of features used only in some instances! Why •  Improve code readability! !
  • 87. Extract Subclass! Event +Start: DateTime +Duration: TimeSpan +Repeat: EventPeriodicity Event +Start: DateTime +Duration: TimeSpan PeriodicEvent +Repeat: EventPeriodicity
  • 88. Extract Superclass! Create superclass and move common features! When •  Several classes have the same subset of features! Why •  Remove duplication! !
  • 89. Extract Superclass! AccountTransaction +Change: decimal +Saldo: decimal +TradeDate: DateTime Transaction +Change: decimal +TradeDate: DateTime Order +Amount: int +Price: decimal +Change: decimal +Security: Security +TradeDate: DateTime AccountTransaction +Saldo: decimal Order +Amount: int +Price: decimal +Security: Security
  • 90. Replace Inheritance with Delegation! Put superclass to a field and use delegation! When •  Unable to say “subclass is a superclass”! •  Subclass implements superclass interface partially! Why •  Simplify design! !
  • 91. Replace Inheritance with Delegation! Array +Insert(T item) +IsEmpty() Stack +Push(T Item) +Pop(): T Array +Insert(T item) +IsEmpty() Stack +Push(T Item) +Pop(): T +IsEmpty() -array return _array.IsEmpty();
  • 92. Architectural Refactorings! Tease Apart Hierarchies. Extract Hierarchy. Convert Procedural Design to Objects. Separate Domain from Presentation. !
  • 93. Tease Apart Inheritance! Create two hierarchies using one another! When •  The inheritance hierarchy has two responsibilities! Why •  Simplify design! !
  • 95. Extract Hierarchy! Create hierarchy with subclass per special case! When •  The single class overwhelmed with conditionals! Why •  Improve code readability! •  Improve architecture! !
  • 97. Convert Procedural Design to Objects! Turn data into objects and behavior into methods! When •  The classes with long methods but without fields! •  The classes with fields but without methods! Why •  Improve code readability! •  Improve architecture! !
  • 98. Convert Procedural Design to Objects! OrderCalculator +CalculatePrice(order) +CalculateTaxes(order) OrderOrderLine Order +Price() +Taxes() OrderLine +Price() +Taxes() 1 *
  • 99. Separate Domain from Presentation ! Create domain logic classes separated from ui! When •  UI logic is mixed with domain logic! Why •  Improve code readability! •  Improve architecture! !
  • 100. Separate Domain from Presentation! ClientPage (business logic embedded) ClientClientPage 1
  • 101. Thank you!! Your questions, please!! ARTEM TABALIN!
  • 102. References! •  Martin Fowler Refactoring! •  Robert C. Martin Clean Code! •  Steve McConnell Code Complete!!