SlideShare a Scribd company logo
31 DAYS OF
REFACTORING
PREPARED BY
Ahasanul Kalam Akib
1. Encapsulate Collection
• when there is additional logic associated with adding/removing items from a collection,
it is a good idea to only expose the collection as something you can iterate over without
modifying the collection.
• Using this can ensure that consumers do not mis-use your collection and introduce bugs
into the code.
1. Encapsulate Collection Example
we have encapsulated the collection as to
not expose the Add/Remove methods to
consumers of this class.
2. Move Method
• Move method does exactly what it sounds like
• Move a method to a better location
2. Move Method Example (Before Ref.)
2. Move Method Example (After Ref.)
3. PULL UP Method
• The process of taking a method and “Pulling” it up in the inheritance chain
• This is used when a method needs to be used by multiple implementers.
3. PULL UP Method Example (Before Ref.)
Here Turn() method is currently only available
to the car class, we also want to use it in the
motorcycle class so we create a base class if
one doesn’t already exist and “pull up” the
method into the base class making it available
to both.
3. PULL UP Method Example (After Ref.)
4. PUSH Down Method
• Opposite of PULL UP method.
Dog could bark, but now there no longer need that functionality on the
Cat class. So we “Push Down” the Bark() method into the Dog class
Refactoring
5. PULL UP Field
• Like PULL UP method, we also need to PULL UP FIELD
• When we have a constant value that is duplicated between two derived classes. To
promote reuse we can pull up the field into the base class and rename it for brevity.
5. PULL UP Field Example
Here _minimumCheckingBalance and
_minimumSavingsBalance are duplicate. So here we
can refactoring by using another variable in BASE
Class
Refactoring
6. Push Down Field
• Opposite of the Pull Up Field refactoring is push down field
• It’s important to do this refactoring at the moment the base field is no longer used by other derived classes.
Here a string field named _resolution that is only used by one derived
class, and thus can be pushed down as no other classes are using it.
Refactoring
7. Rename (METHOD, CLASS, PARAMETER)
• Avoid misunderstanding about Method, Class, Parameter
Refactoring
8. Replace Inheritance With Delegation
• Inheritance should only be used in logical circumstances but it is often used for convenience purposes
Refactoring
In this instance, a Child is not a “Sanitation” and therefore doesn’t make
sense as an inheritance hierarchy. We can refactor by initializing an
instance of Sanitation in the Child constructor and delegating the call to
the class rather than via inheritance
9. Extract Interface
• When you notice more than one class using a similar subset of methods on a class, it is useful
to break the dependency and introduce an interface that the consumers to use.
9. Extract Interface Example (After Ref)
In this example, you can see we extracted the
methods that both consumers use and placed them
in an interface. Now the consumers don’t care/know
about the class that is implementing these methods.
We have decoupled our consumer from the actual
implementation and depend only on the contract
that we have created.
10. Extract Method
• It helps to make code more readable by placing logic behind descriptive method names.
• This reduces the amount of investigation the next developer needs to do as a method
name can describe what a portion of code is doing.
• This in turn reduces bugs in the code because less assumptions need to be made.
10. Extract Method Example (Before Ref)
You can see that the CalculateGrandTotal
method is actually doing three different
things here. It’s calculating the subtotal,
applying any discounts and then calculating
the tax for the receipt. Instead of making a
developer look through that whole method
to determine what each thing is doing, it
would save time and readability to seperate
those distinct tasks into their own methods
10. Extract Method Example (After Ref)
11. Switch To Strategy
• This refactoring is used when you have a larger switch statement that continually
changes because of new conditions being added.
• In these cases it’s often better to introduce the strategy pattern and encapsulate each
condition in it’s own class.
11. Switch To Strategy (Before Ref)
11. Switch To Strategy (After Ref)
Here is the implementation with the ShippingCalculations
dictionary. this is not the only option to implement the
strategy pattern.
12. Break Dependencies
• When any problem occurs with UNIT testing and tight dependency between two classes,
there need to be break dependencies.
• We can break dependencies by introducing a Interface.
In this example we have client code that is
using a static class to accomplish some work.
The problem with this when it comes to unit
testing because there is no way to mock the
static class from our unit test. To work around
this you can apply a wrapper interface around
the static to create a seam and break the
dependency on the static.
12. Break Dependencies Example (After Ref.)
So the behavior is still the same, just the manner in which it is invoked has changed. This is good to get a starting
point to begin refactoring from and an easy way to add unit tests to your code base.
13. Extract Method Object
• When trying to apply an Extract Method refactoring, and multiple methods are needing to be
introduced, it is sometimes gets ugly because of multiple local variables that are being used
within a method.
• Because of this reason, it is better to introduce an Extract Method Object refactoring and to
segregate the logic required to perform the task.
13. Extract Method Object Example (Before Ref.)
13. Extract Method Object Example (After Ref.)
14. Break Responsibilities
the Video class has three
responsibilities, once for handling
video rentals, and another for
managing how many rentals a
customer has. We can break out the
customer logic into it’s own class to
help separate the responsibilities.
14. Break Responsibilities Example (After Ref.)
15. Remove Duplication
• One of the most used refactoring in the forms of methods that are used in more than
one place.
• Duplication will quickly sneak up on you if you’re not careful and give in to apathy.
Refactoring
16. Encapsulate Conditional
• when doing a number of different checks within a conditional the intent of what you are
testing for gets lost in the conditional. In these instances we have to extract the
conditional into an easy to read property, or method depending if there is parameters to
pass or not.
Refactoring
17. Extract Superclass
• This refactoring is used quite often when you have a number of methods that you want
to “pull up” into a base class to allow other classes in the same hierarchy to use.
Refactoring
18. Replace Exception With Conditional
Refactoring
19. Extract Factory Class
• Often in code some involved setup of objects is required in order to get them into a state where we
can begin working with them.
• Usually this setup is nothing more than creating a new instance of the object and working with it in
whatever manner we need.
• Sometimes however the creation requirements of this object may grow and clouds the original
code that was used to create the object. This is where a Factory class comes into play.
19. Extract Factory Class (After Refactoring)
20. Extract Subclass
Refactoring
• This refactoring is useful when you have methods on a base class that are not shared
amongst all classes and needs to be pushed down into it’s own class
21. Collapse Hierarchy
Refactoring
• A Collapse Hierarchy refactoring would be applied when you realize you no longer need a
subclass. When this happens it doesn’t really make sense to keep your subclass around if
it’s properties can be merged into the base class and used strictly from there.
22. Break Method
• This refactoring is kind of a meta-refactoring in the fact that it’s just extract method applied
over and over until you decompose one large method into several smaller methods.
22. Break Method (After Ref.)
• This refactoring is kind of a meta-refactoring in the fact that it’s just extract method applied
over and over until you decompose one large method into several smaller methods.
23. Introduce Parameter Object
Refactoring
• Sometimes when working with a method that needs several parameters it becomes difficult
to read the method signature because of five or more parameters being passed to the
method.
24. Remove Arrowhead Antipattern
• The arrowhead antipattern is when you have nested conditionals so deep that they form an
arrowhead of code.
• It makes for high cyclomatic complexity in code.
24. Remove Arrowhead Antipattern (Before Ref.)
24. Remove Arrowhead Antipattern (After Ref.)
Refactoring away
from the
arrowhead
antipattern is as
simple as
swapping the
conditionals to
leave the method
as soon as
possible.
25. Introduce Design By Contract Checks
• Design By Contract or DBC defines that methods should have defined input and output
verifications.
• Therefore, you can be sure you are always working with a usable set of data in all methods
and everything is behaving as expected.
• If not, exceptions or errors should be returned and handled from the methods.
25. Introduce Design By Contract Checks (Before Ref.)
In our example here, we are working with input parameters that may possibly be null. As a result a
NullReferenceException would be thrown from this method because we never verify that we have an instance.
During the end of the method, we don’t ensure that we are returning a valid decimal to the consumer of this
method
25. Introduce Design By Contract Checks (After Ref.)
26. Remove Double Negative
• This refactoring is pretty simple to implement although I find it in many codebases that
severely hurts readability and almost always conveys incorrect intent.
• This type of code does the most damage because of the assumptions made on it.
Assumptions lead to incorrect maintenance code written, which in turn leads to bugs
26. Remove Double Negative (After Ref.)
As we can see the double
negative here is difficult to read
because we have to figure out
what is positive state of the two
negatives.
The fix is very easy. If we don’t
have a positive test, add one that
does the double negative
assertion for you rather than
make sure you get it correct.
27. Remove God Classes
• A God Class’s object that knows too much or does too much.
• God class grouped methods together with using statements or comments into separate
roles that this one class is performing.
• Over time, these classes become a dumping ground for a method that someone doesn’t
have time/want to put in the proper class
27. Remove God Classes (Before Ref.)
The refactoring for this is
very straight forward.
Simply take the related
methods and place them in
specific classes that match
their responsibility.
27. Remove God Classes (After Ref.)
28. Rename Boolean Method
• Methods with a large number of Boolean parameters can quickly get out of hand and can
produce unexpected behavior.
• Depending on the number of parameters will determine how many methods need to be
broken out.
We can make this work a little better
simple by exposing the Boolean
parameters via well named methods and
in turn make the original method private
to prevent anyone from calling it going
forward.
29. Remove Middle Man
• Middle Men classes simply take calls and forward them on to other components without
doing any work. This is an unneeded layer and can be removed completely with minimal
effort.
29. Remove Middle Man (After Ref.)
30. Return ASAP
• The idea is that as soon as you know what needs to be done and you have all the required
information, you should exit the method as soon as possible and not continue along.
31. Replace Conditional With Polymorphism
• In instances where you are doing checks by type, and performing some type of operation, it’s a
good idea to encapsulate that algorithm within the class and then use polymorphism to abstract
the call to the code.
31. Replace Conditional With Polymorphism (After Ref.)
Reference
• 31 Days of Refactoring Useful refactoring techniques you have to know
-Sean Chambers, Simone Chiaretta (October 2009)
Thank You…

More Related Content

31 days Refactoring

  • 1. 31 DAYS OF REFACTORING PREPARED BY Ahasanul Kalam Akib
  • 2. 1. Encapsulate Collection • when there is additional logic associated with adding/removing items from a collection, it is a good idea to only expose the collection as something you can iterate over without modifying the collection. • Using this can ensure that consumers do not mis-use your collection and introduce bugs into the code.
  • 3. 1. Encapsulate Collection Example we have encapsulated the collection as to not expose the Add/Remove methods to consumers of this class.
  • 4. 2. Move Method • Move method does exactly what it sounds like • Move a method to a better location
  • 5. 2. Move Method Example (Before Ref.)
  • 6. 2. Move Method Example (After Ref.)
  • 7. 3. PULL UP Method • The process of taking a method and “Pulling” it up in the inheritance chain • This is used when a method needs to be used by multiple implementers.
  • 8. 3. PULL UP Method Example (Before Ref.) Here Turn() method is currently only available to the car class, we also want to use it in the motorcycle class so we create a base class if one doesn’t already exist and “pull up” the method into the base class making it available to both.
  • 9. 3. PULL UP Method Example (After Ref.)
  • 10. 4. PUSH Down Method • Opposite of PULL UP method. Dog could bark, but now there no longer need that functionality on the Cat class. So we “Push Down” the Bark() method into the Dog class Refactoring
  • 11. 5. PULL UP Field • Like PULL UP method, we also need to PULL UP FIELD • When we have a constant value that is duplicated between two derived classes. To promote reuse we can pull up the field into the base class and rename it for brevity.
  • 12. 5. PULL UP Field Example Here _minimumCheckingBalance and _minimumSavingsBalance are duplicate. So here we can refactoring by using another variable in BASE Class Refactoring
  • 13. 6. Push Down Field • Opposite of the Pull Up Field refactoring is push down field • It’s important to do this refactoring at the moment the base field is no longer used by other derived classes. Here a string field named _resolution that is only used by one derived class, and thus can be pushed down as no other classes are using it. Refactoring
  • 14. 7. Rename (METHOD, CLASS, PARAMETER) • Avoid misunderstanding about Method, Class, Parameter Refactoring
  • 15. 8. Replace Inheritance With Delegation • Inheritance should only be used in logical circumstances but it is often used for convenience purposes Refactoring In this instance, a Child is not a “Sanitation” and therefore doesn’t make sense as an inheritance hierarchy. We can refactor by initializing an instance of Sanitation in the Child constructor and delegating the call to the class rather than via inheritance
  • 16. 9. Extract Interface • When you notice more than one class using a similar subset of methods on a class, it is useful to break the dependency and introduce an interface that the consumers to use.
  • 17. 9. Extract Interface Example (After Ref) In this example, you can see we extracted the methods that both consumers use and placed them in an interface. Now the consumers don’t care/know about the class that is implementing these methods. We have decoupled our consumer from the actual implementation and depend only on the contract that we have created.
  • 18. 10. Extract Method • It helps to make code more readable by placing logic behind descriptive method names. • This reduces the amount of investigation the next developer needs to do as a method name can describe what a portion of code is doing. • This in turn reduces bugs in the code because less assumptions need to be made.
  • 19. 10. Extract Method Example (Before Ref) You can see that the CalculateGrandTotal method is actually doing three different things here. It’s calculating the subtotal, applying any discounts and then calculating the tax for the receipt. Instead of making a developer look through that whole method to determine what each thing is doing, it would save time and readability to seperate those distinct tasks into their own methods
  • 20. 10. Extract Method Example (After Ref)
  • 21. 11. Switch To Strategy • This refactoring is used when you have a larger switch statement that continually changes because of new conditions being added. • In these cases it’s often better to introduce the strategy pattern and encapsulate each condition in it’s own class.
  • 22. 11. Switch To Strategy (Before Ref)
  • 23. 11. Switch To Strategy (After Ref) Here is the implementation with the ShippingCalculations dictionary. this is not the only option to implement the strategy pattern.
  • 24. 12. Break Dependencies • When any problem occurs with UNIT testing and tight dependency between two classes, there need to be break dependencies. • We can break dependencies by introducing a Interface. In this example we have client code that is using a static class to accomplish some work. The problem with this when it comes to unit testing because there is no way to mock the static class from our unit test. To work around this you can apply a wrapper interface around the static to create a seam and break the dependency on the static.
  • 25. 12. Break Dependencies Example (After Ref.) So the behavior is still the same, just the manner in which it is invoked has changed. This is good to get a starting point to begin refactoring from and an easy way to add unit tests to your code base.
  • 26. 13. Extract Method Object • When trying to apply an Extract Method refactoring, and multiple methods are needing to be introduced, it is sometimes gets ugly because of multiple local variables that are being used within a method. • Because of this reason, it is better to introduce an Extract Method Object refactoring and to segregate the logic required to perform the task.
  • 27. 13. Extract Method Object Example (Before Ref.)
  • 28. 13. Extract Method Object Example (After Ref.)
  • 29. 14. Break Responsibilities the Video class has three responsibilities, once for handling video rentals, and another for managing how many rentals a customer has. We can break out the customer logic into it’s own class to help separate the responsibilities.
  • 30. 14. Break Responsibilities Example (After Ref.)
  • 31. 15. Remove Duplication • One of the most used refactoring in the forms of methods that are used in more than one place. • Duplication will quickly sneak up on you if you’re not careful and give in to apathy. Refactoring
  • 32. 16. Encapsulate Conditional • when doing a number of different checks within a conditional the intent of what you are testing for gets lost in the conditional. In these instances we have to extract the conditional into an easy to read property, or method depending if there is parameters to pass or not. Refactoring
  • 33. 17. Extract Superclass • This refactoring is used quite often when you have a number of methods that you want to “pull up” into a base class to allow other classes in the same hierarchy to use. Refactoring
  • 34. 18. Replace Exception With Conditional Refactoring
  • 35. 19. Extract Factory Class • Often in code some involved setup of objects is required in order to get them into a state where we can begin working with them. • Usually this setup is nothing more than creating a new instance of the object and working with it in whatever manner we need. • Sometimes however the creation requirements of this object may grow and clouds the original code that was used to create the object. This is where a Factory class comes into play.
  • 36. 19. Extract Factory Class (After Refactoring)
  • 37. 20. Extract Subclass Refactoring • This refactoring is useful when you have methods on a base class that are not shared amongst all classes and needs to be pushed down into it’s own class
  • 38. 21. Collapse Hierarchy Refactoring • A Collapse Hierarchy refactoring would be applied when you realize you no longer need a subclass. When this happens it doesn’t really make sense to keep your subclass around if it’s properties can be merged into the base class and used strictly from there.
  • 39. 22. Break Method • This refactoring is kind of a meta-refactoring in the fact that it’s just extract method applied over and over until you decompose one large method into several smaller methods.
  • 40. 22. Break Method (After Ref.) • This refactoring is kind of a meta-refactoring in the fact that it’s just extract method applied over and over until you decompose one large method into several smaller methods.
  • 41. 23. Introduce Parameter Object Refactoring • Sometimes when working with a method that needs several parameters it becomes difficult to read the method signature because of five or more parameters being passed to the method.
  • 42. 24. Remove Arrowhead Antipattern • The arrowhead antipattern is when you have nested conditionals so deep that they form an arrowhead of code. • It makes for high cyclomatic complexity in code.
  • 43. 24. Remove Arrowhead Antipattern (Before Ref.)
  • 44. 24. Remove Arrowhead Antipattern (After Ref.) Refactoring away from the arrowhead antipattern is as simple as swapping the conditionals to leave the method as soon as possible.
  • 45. 25. Introduce Design By Contract Checks • Design By Contract or DBC defines that methods should have defined input and output verifications. • Therefore, you can be sure you are always working with a usable set of data in all methods and everything is behaving as expected. • If not, exceptions or errors should be returned and handled from the methods.
  • 46. 25. Introduce Design By Contract Checks (Before Ref.) In our example here, we are working with input parameters that may possibly be null. As a result a NullReferenceException would be thrown from this method because we never verify that we have an instance. During the end of the method, we don’t ensure that we are returning a valid decimal to the consumer of this method
  • 47. 25. Introduce Design By Contract Checks (After Ref.)
  • 48. 26. Remove Double Negative • This refactoring is pretty simple to implement although I find it in many codebases that severely hurts readability and almost always conveys incorrect intent. • This type of code does the most damage because of the assumptions made on it. Assumptions lead to incorrect maintenance code written, which in turn leads to bugs
  • 49. 26. Remove Double Negative (After Ref.) As we can see the double negative here is difficult to read because we have to figure out what is positive state of the two negatives. The fix is very easy. If we don’t have a positive test, add one that does the double negative assertion for you rather than make sure you get it correct.
  • 50. 27. Remove God Classes • A God Class’s object that knows too much or does too much. • God class grouped methods together with using statements or comments into separate roles that this one class is performing. • Over time, these classes become a dumping ground for a method that someone doesn’t have time/want to put in the proper class
  • 51. 27. Remove God Classes (Before Ref.) The refactoring for this is very straight forward. Simply take the related methods and place them in specific classes that match their responsibility.
  • 52. 27. Remove God Classes (After Ref.)
  • 53. 28. Rename Boolean Method • Methods with a large number of Boolean parameters can quickly get out of hand and can produce unexpected behavior. • Depending on the number of parameters will determine how many methods need to be broken out. We can make this work a little better simple by exposing the Boolean parameters via well named methods and in turn make the original method private to prevent anyone from calling it going forward.
  • 54. 29. Remove Middle Man • Middle Men classes simply take calls and forward them on to other components without doing any work. This is an unneeded layer and can be removed completely with minimal effort.
  • 55. 29. Remove Middle Man (After Ref.)
  • 56. 30. Return ASAP • The idea is that as soon as you know what needs to be done and you have all the required information, you should exit the method as soon as possible and not continue along.
  • 57. 31. Replace Conditional With Polymorphism • In instances where you are doing checks by type, and performing some type of operation, it’s a good idea to encapsulate that algorithm within the class and then use polymorphism to abstract the call to the code.
  • 58. 31. Replace Conditional With Polymorphism (After Ref.)
  • 59. Reference • 31 Days of Refactoring Useful refactoring techniques you have to know -Sean Chambers, Simone Chiaretta (October 2009)