Contenu connexe Similaire à Code Refactoring (20) Plus de Harbinger Systems - HRTech Builder of Choice (20) Code Refactoring1. HSTP3301
Code Refactoring
Johnson Goveas
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
2. Refactoring
– Refactoring refers to structuring the code to:
1. Increase readability of code
2. Fix bugs easily
3. Enhance design
4. Introduce flexibility to code.
– Refactoring is to restructure or rewrite source code to improve
internal consistency, readability, etc, without changing its
function.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
3. Why to refactor?
– Programs that are hard to read are hard to modify.
– Programs that have duplicated logic are hard to modify.
– Programs that require additional behavior that requires you to
change running code are hard to modify.
– Programs with complex conditional logic are hard to modify.
– To enable sharing of logic. For example, a sub-method invoked
in two different places or a method in a super-class shared by
all subclasses
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
4. Why to refactor? Contd...
– To explain intention and implementation separately. Choosing
the name of each class and the name of each method gives
you an opportunity to explain what you intend.
– To isolate change. Suppose, I use an object in two different
places. I want to change the behavior in one of the two cases.
If I change the object, I risk changing both. So I first make a
subclass and refer to it in the case that is changing.
– To encode conditional logic. Objects have a fabulous
mechanism, polymorphic messages, to flexibly but clearly
express conditional logic. By changing explicit conditionals to
messages, you can often reduce duplication, add clarity, and
increase flexibility all at the same time.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
5. When to refactor?
– Here’s a guideline from Don Roberts: The first time you do
something, you just do it. The second time you do something
similar, you wince at the duplication, but you do the duplicate
thing anyway. The third time you do something similar, you
refactor.
– Refactor during design and analysis (UML diagrams)
– Refactor when you add a function / feature
– Refactor when you fix a bug
– Refactor while code review
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
6. Problems with refactoring
– Be careful while refactoring interfaces. An application using
this interface from your library might stop working properly.
(For example: support of deprecated methods)
– With refactoring you approach the risks of change. Avoid
refactoring of code that effects the application.
– Think about enhancing and adding flexibility to design of the
application while refactoring.
– Even if you know exactly what is going on in your system,
measure performance; don’t speculate.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
7. When not to refactor
– There are times when the existing code is such a mess that
although you could refactor it, it would be easier to start from
the beginning.
– Avoid refactoring when you are close to release deadline. At
that point the productivity gain from refactoring would appear
after the deadline and thus be too late.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
8. How to maintain code in a class
Use proper sections in your classes.
– View lifecycle: Generated default while adding a controller.
– Event handling: Usually for controllers. This section will consist
of methods like click to a button , change in selection, gesture
recognition, etc.
– Overloading methods: Methods overloaded from the super
class
– Delegates / Overriding: Separate section for methods of each
protocol/delegate implemented.
– Fetching data: This section will consists of refreshing UI and
reloading of data.
– Animation: This section will have all animation specific
methods. NOTE: consider refactoring of these methods to
generalize it.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
9. Click to edit Master title style
WHAT TO REFACTOR?
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
10. Duplicate Code
If you see the same code structure (piece of code) in more than
one place, you can be sure that your program will be better if
you find a way to unify them:
– Same code in two methods of the same class - Create a class
method
– Same code in two sibling subclasses - Create method in super
class
– Same code in two unrelated classes - Consider using Extract
Class or Extract Module in one class and then use the new
component in the other. Another possibility is that the method
really belongs only in one of the classes and should be invoked
by the other class or that the method belongs in a third class
that should be referred to by both of the original classes
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
11. Long Methods
– Programs that live best and longest are those with short
methods.
– Longer a procedure is, the more difficult it is to understand.
– Whenever we feel the need to comment something, we should
write a method instead.
– The key here is not method length, but the semantic distance
between what the method does and how it does it.
– How do you identify the clumps of code to extract? A good
technique is to look for comments. Conditionals and loops also
give signs for extractions.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
12. Large Class
– When a class is trying to do too much, it often shows up as too
many instance variables. You can Extract Class to bundle a
number of related variables.
– As with a class with too many instance variables, a class with
too much code is prime breeding ground for duplicated code. If
you have five hundred-line methods with a lot of duplicate
code, you may be able to turn them into five ten-line methods
with another ten two-line method extracted from the original.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
13. Long Parameter List
– If you don’t have something you need, you can always ask
another object to get it for you. Thus with objects you don’t
pass in everything the method needs; instead you pass
enough so that the method can get to everything it needs. A
lot of what a method needs is available on the method’s host
class.
– Example: To convert a date format, instead of creating a
method in a utility class and passing parameter of the date
and format required. We can create a category of date class
with a method that takes the format required. Hence the class
itself now has information for date, which was passed as
parameter earlier.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
14. Divergent Change
– Divergent change occurs when one class is commonly changed
in different ways for different reasons. If you look at a class
and say, “Well, I will have to change these three methods
every time I get a new database; I have to change these four
methods every time there is a new financial instrument,” you
likely have a situation in which two objects are better than
one. That way each object is changed only as a result of one
kind of change.
– Identify everything that changes for a particular cause and use
Extract Class to put them all together.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
15. Shotgun Surgery
– Shotgun surgery is similar to divergent change but is the
opposite. When similar changes are all over the place, they are
hard to find, and it’s easy to miss an important change.
– In this case you want to use Move Method and Move Field to
put all the changes into a single class. If no current class looks
like a good candidate, create one.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
16. Feature Envy
– If a feature / method of a class uses most of the data from
another class for its computation.
– Consider shifting the method to that class instead.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
17. Data Clumps
– Often you might see few data items together in many places:
instance variables in a couple of classes, and parameters in
many method signatures.
– The first step is to look for where the clumps appear as
instance variables. Use Extract Class on the instance variables
to turn the clumps into an object.
– Then for parameters in method signatures, Introduce
Parameter Object or Preserve Whole Object (refer Long
Parameter List section above) to slim them down.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
18. Primitive Obsession
– Do not be hesitant to use wrapper Objects over primitive data
types.
– Do not be hesitant to create a class that may even have 2 or 3
primitive data types.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
19. Case Statements
– Most times when you see a case statement you should
consider polymorphism.
– Often the case statement matches on a type code. Consider
using polymorphism in the class that hosts the type code
value.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
20. Parallel Inheritance Hierarchies
– This is a special case of shotgun surgery.
– In this case, every time you make a subclass of one class, you
also have to make a subclass of another.
– General strategy for eliminating this duplication is to make
sure that instances of one hierarchy refer to instances of the
other.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
21. Lazy Class
– A class that isn’t doing enough to pay for itself should be
eliminated.
– Often this might be a class that used to pay its way but has
been downsized with refactoring.
– Or it might be a class that was added because of changes that
were planned but not made.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
22. Speculative Generality
– You get it when people say, “Oh, I think we need the ability to
do this kind of thing someday” and thus want all sorts of hooks
and special cases to handle things that aren’t required.
– The result often is harder to understand and maintain.
– If all this machinery were being used, it would be worth it. But
if it isn’t, it isn’t. The machinery just gets in the way, so get rid
of it.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
23. Temporary Field
– Sometimes an instance variable is set only in certain
circumstances. Such code is difficult to understand, because
you expect an object to need all of its variables.
– Trying to understand why a variable is there when it doesn’t
seem to be used can drive you nuts.
– Use Extract Class to create a home for the poor orphan
variables. Put all the code that concerns the variables into the
component. You may also be able to eliminate conditional code
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
24. Message Chains
– This occurs when a client asks one object for another object,
which the client then asks for yet another object, which the
client then asks for yet another object, and so on.
– Navigating this way means the client is coupled to the
structure of the navigation. Any change to the intermediate
relationships causes the client to have to change.
– In principle you can apply Hide Delegate to potentially every
object in the chain, but doing this often turns every
intermediate object into a middle man (see the next point).
Often a better alternative is to see what the resulting object is
used for. See whether you can use Extract Method to take a
piece of the code that uses it and then Move Method to push it
down the chain. If several clients of one of the objects in the
chain want to navigate the rest of the way, add a method to do
that.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
25. Middle Man
– If a class’s methods are delegating to this other classes for
data or logic, after a while it is time to use Remove Middle Man
and talk to the object that really knows what’s going on.
– Replace Delegation with Hierarchy to turn the real object into a
module and include it in the middle man. That allows you to
extend behavior without chasing all that delegation.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
26. Inappropriate Intimacy
– Sometimes classes become far too intimate and spend too
much time into each-other's (to and fro calls) classes for
execution.
– See whether you can arrange a Change Bidirectional
Association to Unidirectional. If the classes do have common
interests, use Extract Class to put the commonality in a safe
place and make honest classes of them. Or use Hide Delegate
to let another class act as go-between.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
27. Alternative Classes with Different Interfaces
– Use Rename Method on any methods that do the same thing
but have different signatures for what they do.
– Often this doesn’t go far enough. In these cases the classes
aren’t yet doing enough.
– Keep using Move Method to move behavior to the classes until
the protocols are the same.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
28. Incomplete Library Class
– This technique is used to enhance an existing third party
library.
– Think of using categories / extensions for adding more
functions to existing classes.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
29. Data Class (Model Classes)
– Such classes are dumb data holders and are almost certainly
being manipulated in far too much detail by other classes.
– Use Remove Setting Method on any instance variable that
should not be changed. If you have collection instance
variables, check to see whether they are properly
encapsulated.
– Look for where these getting and setting methods are used by
other classes. Try to use Move Method to move behavior into
the data class.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
30. Refused Bequest
– Subclasses get to inherit the methods and data of their
parents. But what if they don’t want or need what they are
given?
– This means the hierarchy is wrong. You need to create a new
sibling class and push all the unused methods to the sibling.
– That way the parent holds only what is common.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
31. Comments
– If you need a comment to explain what a block of code does,
try Extract Method.
– If the method is already extracted but you still need a
comment to explain what it does, use Rename Method.
– If you need to state some rules about the required state of the
system, use Introduce Assertion.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
32. Disjointed API
– A Library often presents itself as a relatively fine-grained,
disjointed API, with many configuration options.
– Often an individual project will not take advantage of all the
configuration options. The same configuration options will be
used over and over.
– If this is the case, use a Gateway to interact with the API in a
simplified way.
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
33. After Effects
– Increase in reusability across projects – 70 to 80 %
– Ease in bug fixing – around 60 %
– Time saved while creating similar projects – around 50%
– Increase in flexibility of design – around 70 %
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
34. References
1. Application Software Reengineering - By: M. Afshar
Alam and Tendai Padenga
2. Objective-C for Absolute Beginners - By: Gary
Bennett, Mitch Fisher and Bard Less
3. Refactoring: Ruby Edition - By: Jay Fields, Shane
Harvie, Martin Fowler and Kent Beck
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring
35. Click to edit Master title style
Thank You!
Copyright © Harbinger Systems www.harbinger-systems.com Code Rafactoring