Refactoring Refactoring n Refactoring is n n Refactoring

  • Slides: 15
Download presentation
Refactoring

Refactoring

Refactoring n Refactoring is: n n Refactoring is not just any old restructuring n

Refactoring n Refactoring is: n n Refactoring is not just any old restructuring n n restructuring (rearranging) code. . . in a series of small, semantics-preserving transformations (i. e. the code keeps working). . . in order to make the code easier to maintain and modify You need to keep the code working You need small steps that preserve semantics You need to have unit tests to prove the code works There are numerous well-known refactoring techniques n You should be at least somewhat familiar with these before inventing your own 2

When to refactor n You should refactor: n Any time that you see a

When to refactor n You should refactor: n Any time that you see a better way to do things n n You can do so without breaking the code n n “Better” means making the code easier to understand to modify in the future Unit tests are essential for this You should not refactor: n n Stable code (code that won’t ever need to change) Someone else’s code n Unless you’ve inherited it (and now it’s yours) 3

Design vs. coding n n “Design” is the process of determining, in detail, what

Design vs. coding n n “Design” is the process of determining, in detail, what the finished product will be and how it will be put together “Coding” is following the plan In traditional engineering (building bridges), design is perhaps 15% of the total effort In software engineering, design is 85 -90% of the total effort n By comparison, coding is cheap 4

The refactoring environment n n Traditional software engineering is modeled after traditional engineering practices

The refactoring environment n n Traditional software engineering is modeled after traditional engineering practices (= design first, then code) Assumptions: n n n “Agile” software engineering is based on different assumptions: n n The desired end product can be determined in advance Workers of a given type (plumbers, electricians, etc. ) are interchangeable Requirements (and therefore design) change as users become acquainted with the software Programmers are professionals with varying skills and knowledge Programmers are in the best position for making design decisions Refactoring is fundamental to agile programming n Refactoring is sometimes necessary in a traditional process, when the design is found to be flawed 5

A personal view n In my opinion, n Design, because it is a lot

A personal view n In my opinion, n Design, because it is a lot more creative than simple coding, is also a lot more fun n Most small to medium-sized projects could benefit from an agile programming approach n n Admittedly, “more fun” is not necessarily “better”. . . but it does help you retain good programmers We don’t yet know about large projects Most programming methodologies attempt to turn everyone into a mediocre programmer n n Sadly, this is probably an improvement in general These methodologies work less well when you have some very good programmers 6

Back to refactoring n When should you refactor? n n n Any time you

Back to refactoring n When should you refactor? n n n Any time you find that you can improve the design of existing code You detect a “bad smell” (an indication that something is wrong) in the code When can you refactor? n n You should be in a supportive environment (agile programming team, or doing your own work) You should have an adequate set of unit tests 7

Example 1: switch statements n switch statements are very rare in properly designed object-oriented

Example 1: switch statements n switch statements are very rare in properly designed object-oriented code n n Therefore, a switch statement is a simple and easily detected “bad smell” Of course, not all uses of switch are bad A switch statement should not be used to distinguish between various kinds of object There are several well-defined refactorings for this case n The simplest is the creation of subclasses 8

Example 1, continued n class Animal { final int MAMMAL = 0, BIRD =

Example 1, continued n class Animal { final int MAMMAL = 0, BIRD = 1, REPTILE = 2; int my. Kind; // set in constructor. . . String get. Skin() { switch (my. Kind) { case MAMMAL: return "hair"; case BIRD: return "feathers"; case REPTILE: return "scales"; default: return "integument"; } } } 9

Example 1, improved n class Animal { String get. Skin() { return "integument"; }

Example 1, improved n class Animal { String get. Skin() { return "integument"; } } class Mammal extends Animal { String get. Skin() { return "hair"; } } class Bird extends Animal { String get. Skin() { return "feathers"; } } class Reptile extends Animal { String get. Skin() { return "scales"; } } 10

How is this an improvement? n n Adding a new animal type, such as

How is this an improvement? n n Adding a new animal type, such as Amphibian, does not require revising and recompiling existing code Mammals, birds, and reptiles are likely to differ in other ways, and we’ve already separated them out (so we won’t need more switch statements) We’ve gotten rid of the flags we needed to tell one kind of animal from another Basically, we’re now using Objects the way they were meant to be used 11

JUnit tests n n As we refactor, we need to run JUnit tests to

JUnit tests n n As we refactor, we need to run JUnit tests to ensure that we haven’t introduced errors public void test. Get. Skin() { assert. Equals("hair", my. Mammal. get. Skin()); assert. Equals("feathers", my. Bird. get. Skin()); assert. Equals("scales", my. Reptile. get. Skin()); assert. Equals("integument", my. Animal. get. Skin()); } This should work equally well with either implementation The set. Up() method of the test fixture may need to be modified 12

Bad Smell Examples n n You should refactor any time you detect a “bad

Bad Smell Examples n n You should refactor any time you detect a “bad smell” in the code Examples of bad smells include: n n n n n Duplicate Code Long Methods Large Classes Long Parameter Lists Multi location code changes Feature Envy Data Clumps Primitive Obsession We will discuss most or all of these later 13

Eclipse refactorings n Eclipse can perform several refactorings for you: n n n n

Eclipse refactorings n Eclipse can perform several refactorings for you: n n n n n Rename (just about anything) Change method signature Move class to another package Pull up (into a superclass) Push down (into subclasses) Extract interface Generalize types Use supertype where possible Infer generic type arguments Inline method call n n n n Extract method Extract local variable Extract constant Introduce parameter Introduce factory Convert local variable to field Encapsulate field 14

The End 15

The End 15