1 / 29

Refactoring to Patterns

Learn from proven solutions to common coding problems with refactoring and design patterns. Discover the essence of patterns, when to refactor, examples like encapsulation and strategy, and how patterns revolutionize code structuring.

jhawes
Download Presentation

Refactoring to Patterns

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Refactoring to Patterns Ravindra Chilaka Extreme Programming Seminar XP 2004 b

  2. Contents • Patterns Introduction. - What is a pattern? - What makes a pattern? - Why use pattern? • Refactoring. - Refactoring. - Why Refactoring to patterns? - When to Refractor? - Example : Switch Statement. - The Refactoring Environment. • Examples of Refactoring to Patterns. - Extract Adapter. - The Template Method. (continued..)

  3. Contents - Encapsulate Classes with Factory. - Encapsulate Composite with Builder. - Move Embellishment to Decorator. - Replace Conditional Logic with Stratergy. - Replace Hard-Coded Notifications with Observer. • Summary. • Questions ??

  4. Patterns Introduction What is a Pattern: (Definition) • Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.(C. Alexander, “The Timeless Way of Building”, 1979) • „A pattern is a named nugget of insight that conveys the essence of a proven solution to a recurring problem within a certain context amidst competing concerns.“ (Brad Applenton, „Patterns and Software : Essential Concepts and Terminology“,2000)

  5. Patterns Introduction • Patterns describe common ways of doing things. • They are collected by people who spot repeating themes in designs. • They take each theme and describe it so that others can use it. • They capture the static and dynamic structures and collaborations of successful solutions to problems that arise when building applications in a particular domain. • A Pattern is much more than a Model. • Design Patterns describe good solutions to common (or at least, not extremely rare) design problems: • Design Patterns are always specified in UML. • Model-View-Controller is a very common Design Pattern. • Design Patterns describe the higher-level organization of solutions to common problems.

  6. Patterns Introduction • What makes a pattern? • Solve a problem (It must be useful) • Have a Context (Where it can be used) • Recur (Must be relevant in other situations) • Teach (provide sufficient understanding to tailor the solution) • Name (To refer Consistently).

  7. Patterns Introduction • Why use Patterns? Patterns help you learn from other’s successes, instead of your own failures(Mark Johnson (cited by B. Eckel)) • An additional layer of abstraction • separate things that change from things that stay the same • distilling out common factors between a family of similar problems • similar to design • Insightful and clever way to solve a particular class of problems • most general and flexible solution

  8. Refactoring • Refactoring is rearranging existing code while maintaining the same functionality • Refactoring is usually done in terms of applying some Design Pattern • Refactoring is restructuring 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 • Refactoring often modifies or introduces Design Patterns • Refactoring is not just any old restructuring • 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 • You should be at least somewhat familiar with these before inventing your own

  9. Refactoring • Why Refactoring to Patterns ? • To reduce or remove Duplication. • Simplifying the unsimple. • Make our code better at its intention.

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

  11. Example : switch statements • switch statements are very rare in properly designed object-oriented code. • 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 • The simplest is the creation of subclasses.

  12. Example, continued • class Animal { final int MAMMAL = 0, BIRD = 1, REPTILE = 2; int myKind; // set in constructor ... String getSkin() { switch (myKind) { case MAMMAL: return "hair"; case BIRD: return "feathers"; case REPTILE: return "scales"; default: return "integument"; } }}

  13. Example, continued • class Animal { String getSkin() { return "integument"; }}class Mammal extends Animal { String getSkin() { return "hair"; }}class Bird extends Animal { String getSkin() { return "feathers"; }}class Reptile extends Animal { String getSkin() { return "scales"; }}

  14. How is this an improvement? • 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.

  15. JUnit tests • As we refactor, we need to run JUnit tests to ensure that we haven’t introduced errors • public void testGetSkin() { assertEquals("hair", myMammal.getSkin()); assertEquals("feathers", myBird.getSkin()); assertEquals("scales", myReptile.getSkin()); assertEquals("integument", myAnimal.getSkin());} • This should work equally well with either implementation • The setUp() method of the test fixture may need to be modified

  16. The Refactoring Environment • Traditional software engineering is modeled after traditional engineering practices (= design first, then code) • Assumptions: • The desired end product can be determined in advance • Workers of a given type (plumbers, electricians, etc.) are interchangeable • “Agile” software engineering is based on different assumptions: • 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 • Refactoring is sometimes necessary in a traditional process, when the design is found to be flawed

  17. Examples of Refactoring to Patterns • Extract Adapter • The Template Method • Encapsulate Classes with Factory • Encapsulate Composite with Builder • Move Embellishment to Decorator • Replace Conditional Logic with Strategy • Replace Hard-Coded Notifications with Observer

  18. Examples of Refactoring to Patterns • Extract Adapter: One Class adapts multiple versions of component, library, API or other Entity. • Solution: Extract an Adapter for a single version of the component , library, API or other Entity.

  19. Examples of Refactoring to Patterns • The Template Method: • Template Methods lead to an inverted control structure • A superclass calls methods in its subclass • Template methods are so fundamental that they can be found in almost every abstract class • Template Method uses inheritance • A similar pattern, Strategy Pattern, uses delegation rather than inheritance

  20. Examples of Refactoring to Patterns • Example : Big fish and little fish • The scenario: “big fish” and “little fish” move around in an “ocean” • Fish move about randomly • A big fish can move to where a little fish is (and eat it) • A little fish will not move to where a big fish is

  21. Examples of Refactoring to Patterns • General outline of the method: • public void move() {choose a random direction; // same for bothfind the location in that direction; // same for bothcheck if it’s ok to move there; // differentif it’s ok, make the move; // same for both} • Solution: • Extract the check on whether it’s ok to move • In the Fish class, put the actual (template) move() method • Create an abstract okToMove() method in the Fish class • Implement okToMove() in each subclass

  22. Note how this works: When a BigFish tries to move, it uses the move() method in Fish But the move() method in Fish uses the okToMove(locn) method in BigFish And similarly for LittleFish Fish Fish move() <<abstract>>okToMove(locn):boolean <<abstract>>move() BigFish BigFish LittleFish BigFish okToMove(locn):boolean move() okToMove(locn):boolean move() Examples of Refactoring to Patterns

  23. Examples of Refactoring to Patterns • Encapsulates Classes with Factory: Clients directly instantiate classes that reside in one package and implement a common interface. • Solution: Make the class constructors non-public and let clients creates instances of them using a factory.

  24. Types of Refactoring to Patterns • Encapsulate Composite with Builder: Building a composite is repititive , complicated or error-prone. • Solution: Simplify the build by letting the Builder handles the details.

  25. Examples of Refactoring to Patterns • Embellishment to Decorator: Code Provides an embellishment to a class‘ core responsibility. • Solution: Move the embellishment code to a Decorator.

  26. Examples of Refactoring to Patterns • Replace Conditional Logic with Stratergy: conditional logic in a method controls which of several variants of a calculation are executed. • Solution: create a Stratergy for each variant and make the method delegate the caliculation to a single stratergy.

  27. Examples of Refactoring to Patterns • Replace Hard-Coded Notifications with Observer: Subclasses are hardcoded to notify a single instance of another class. • Solution: Remove the subclasses by making their superclass capable of notifying one or more instances of any classes that implement a observable interface.

  28. Summary • Patterns describe common ways of doing things. They are collected by people who spot repeating themes in designs. • We should refactor any time we detect a “bad smell” in the code. Refactoring makes code easier to understand, maintain and modify. • Various Refactoring techniques to the patterns can be applied to the real-world problems depending up on the application criteria and usage of the system. (For e.g.: Observer ,Strategy and Template Patterns, etc. are most commonly used).

  29. Questions ?? ? ? ?

More Related