Design Patterns and Refactoring - PowerPoint PPT Presentation

design patterns and refactoring n.
Skip this Video
Loading SlideShow in 5 Seconds..
Design Patterns and Refactoring PowerPoint Presentation
Download Presentation
Design Patterns and Refactoring

play fullscreen
1 / 76
Design Patterns and Refactoring
Download Presentation
Download Presentation

Design Patterns and Refactoring

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Design Patterns and Refactoring CSC 2053

  2. Buzzwords • Design Patternsdescribe the higher-level organization of solutions to common problems • Design Patterns are a current hot topic in O-O design

  3. Design Patterns • Design Patterns are always described in UML notation • UML is a diagramming language designed for Object-Oriented programming • Design Patterns are used to describe refactorings

  4. Design Patterns • Refactoringis restructuring code in a series of small, semantics-preserving transformations • (i.e. keeps the code working) in order to make the code easier to maintain and modify • Refactoring often modifies or introduces Design Patterns

  5. UML • UML stands for Unified Modeling Language • UML is a complicated diagramming language designed for Object-Oriented programming

  6. UML • UML comprises at least seven or eight different kinds of diagrams that can be used to describe: • the organization of a program • how a program executes • how a program is used • how a program is deployed over a network • …and more • We will just deal here with the class diagram

  7. Example: Card cardId:int -copy:boolean=false «constructor» Card(int id) +isKind(desiredKind:int) +isSharable():boolean +toString():String Name of the class Variables [optional] Methods UML class diagrams • Key: • + means public visibility • # means protected visibility • - means private visibility • <blank> means default (package) visibility • static variables are underlined

  8. UML relationships A B C D Factory Product A B creates 1..4 Class Ccontains 1 to 4 objectsof class D Class Bextendsclass A Class Bimplementsinterface A Other kinds ofrelations

  9. Design patterns • It is important in designing object-oriented software that you develop: • a good design, that is reusable, • able to address future problems.

  10. Design Patterns • Many design patterns have been established over the years that can help you do this. • Good software developers reuse solutions that have worked in the past. • So you will find recurring patterns of classes and communicating objects in many systems.

  11. Problem I: Uncertain delegation • Through polymorphism you can just send a message to an object, • and the object does the right thing, depending on its type • However, you must check first that the object is not null: • if (myObject != null) myObject.doSomething();

  12. EXAMPLES OF NULL OBJECTS • You have an Ocean, represented by a sparse array containing a few Fish • You have a TrafficGrid, some cells of which contains Cars and Trucks and others are empty • You want to send output to some port potentially closed

  13. NULL OBJECTS • If you use these types of objects a lot: • your code can end up cluttered with tests for null • We need a Design Pattern to help us

  14. Solution: Null Object • So create another kind of object, a “null object,” • representing the absence of any other kind of object • E. G.: An Ocean might contain Inhabitants • So class Inhabitant can be sub classed by • BigFish, LittleFish, Algae, and NothingButWater

  15. ABSTRACT CLASS INHABITANTS LittleFish INHABITANTS HIERARCHY abstract void REPRODUCE(); Nothing But Water Big Fish REPRODUCE() { SOME CODE} REPRODUCE(){ SOME CODE}; REPRODUCE() ; NO CODE; So class Inhabitanthas three sub classes: 1. BigFish, 2. LittleFish, Algae, and NothingButWater 15 15

  16. Null Object • This way, no location in the Ocean is null • If Inhabitant class contains a method reproduce(), • the subclass NothingButWatercould implement this method with an empty method body

  17. Refactoring: Introduce Null Objects • The general idea is simple, refactor: • Instead of having some variables (locations in the array) be null, have them be “null objects” • However, this may require numerous changes in the code

  18. Refactoring • Changing working code is hazardous — • you introduce bugs that it can take days to find . • Solution: REFACTOR

  19. Refactoring: to make it safe do: • Refactoring has three pillars: • Introduce the Null Objects in small steps, • having an automated set of unit tests, and • running unit tests frequently, so when errors occur you can pinpoint it immediately

  20. Introduce Null Object: In detail • Create a subclass of the source class to act as a null version of the class. • Create an isNull() method in the source class and in the Null class. • For the source class it should return false, for the Null class it should return true. • All other subclasses of the source will inherit its version

  21. Source Class <<abstract>>isNull() Null Class isNull() return True IsNull() as an Abstract method Normal class isNull() return False

  22. Source Class booleanisNull() return false Null Class isNull() return True IsNull() is not an abstract method The Null class overrides the parent class isNull() method Normal class isNull() Is inherited

  23. Null Object After creating the Null Object class: • Compile. • Find all places that produce a nullwhen asked for a source object. • Replace them with a null object instead. • Replace one source and its clients at a time

  24. Introduce Null Object: In detail, II • When the result is null for an operation, • do some alternative behavior instead. • E.g. return a string “Nothing But Water”. • For each of these cases, override the operation in the Null class with the alternative behavior. • Compile, and test.

  25. Source Class <<abstract>>isNull() Null Class isNull() return True INSTEAD OF THIS CODE : Normal class Normal class isNull() Return False isNull() Return False

  26. USE AN ALTERNATIVE BEHAVIOR booleanisNull() return false Null Class Normal Class isNull() return “Nothing but Water” isNull() Is inherited

  27. Refactoring details • IMPORTANT: • Use “baby steps” • Do the refactoring a little at a time, • so that it’s very easy to catch and correct errors

  28. USE TESTS THAT ARE already implemented. • IMPORTANT - USE a good set of : • totally automated tests — already implemented. • Otherwise the testing is just too much work, and you won’t do it • JUnitis a great start

  29. Scenario: 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

  30. Fish <<abstract>>move() BigFish LittleFish move() move() We implement move methods in sub classes which are almost the same

  31. Problem: Similar methods in subclasses • We have a Fishclass with two subclasses, • BigFish and LittleFish • The two kinds move the same way • except a little fish won’t move near a big fish. • To avoid code duplication, the move method ought to be in the superclass Fish

  32. Problem - • Since a LittleFish won’t move to some locations where a BigFish will move • The test for whether it is OK to move really ought to be in themove method in the sub classes • More generally, you want to have almostthe same method in two or more sibling classes

  33. The move() method • General outline of the method: public void move() {choose a random direction;// same for both find the location in that direction; // same for both check if it’s ok to move there; // different if it’s ok, make the move; // same for both}

  34. Fish <<abstract>>move() BigFish LittleFish move() move() The Fish refactoring – Phase 1 • Note how first version works: • When a BigFish tries to move, • it overrides the move()method it inherits from Fish

  35. Solution - Template Method • Write the oktoMove() method as an abstract method in the super class • This in turn requires that the super class be abstract

  36. ReFactoring -step by step • To refactor: • Extract the check on whether it’s ok to move • In the Fish class, put the actual (template)move() method • Create an abstractokToMove()method in the Fish class • ImplementokToMove() differently in each subclass

  37. Fish Fish move() : implemented <<abstract>>okToMove(locn):boolean <<abstract>>move() BigFish BigFish LittleFish LittleFish okToMove(locn):boolean move() okToMove(locn):boolean move() The Fish refactoring: Phase II • Note how revised version works: • When a BigFish tries to move, it uses the move()method it inherits from Fish • BigFish and LittleFish implement their own okToMove(locn)

  38. Template Design • The Design Pattern is called “Template Method”; • The refactoring is called “Form Template Method”.

  39. Problem: Constructors create objects • Constructors make objects. • Only constructors can make objects. • When you call a constructor of a class, • you will get an instance of that class.

  40. Singleton classes • Sometimes you want more flexibility than that— • YOU WANT TO: • guarantee that you can never have more than one object of a given class • create an object only if you don’t already have an equivalent object • create an object without being sure exactly what kind of object you want

  41. Constructors • Although only constructors make objects • You don’t have to call constructors directly— • you can call a method that calls the constructor for you • Several “creational” Design Patterns are based on this observation

  42. Singleton Design Pattern –A Creational Design Pattern • ASingleton Design pattern provides a model for building a class that can have only one instance • You may want just one instance of a null object, which you use in many places • Or - to create just one AudioStream, so you can only play one tune at a time

  43. Singleton Design Pattern • You may want to have many printers but one spooler • You might want to have one copy of alphabetic characters in a document

  44. Singleton classes • The method : • define a static reference variable of the class type which serves as the single instance of the class. • Make the constructor private so a user can not instantiate the class • Use a static public method that returns the reference to the object

  45. Singleton Design Pattern class Singleton { // create a single instance of the classprivate static Singleton instance = new Singleton(); // don’t let Java give you a default public constructor private Singleton() { } // Have a method that returns the instance of the classpublic static Singleton getInstance() { return instance; } ...} See

  46. Singleton Design Pattern public class Dice { // static reference dice identifies the single class instance private static Dice dice = null; private Random rnd; private int dice1, dice2; // private constructor is called by the method getDice() // to create a single instance of the class private Dice() { // create a random number generator rnd = new Random(); }

  47. Singleton Design Pattern /*if no object currently exists, the method calls the private constructor to create an instance; if an object exists, method returns the static reference variable*/ public static Dice getDice() { if (dice == null) { dice = new Dice(); // create a single dice object } return dice; //the single reference to the class } // other methods in the class

  48. The Factory Method Design Pattern • Suppose you write a class that works with several different kinds of objects • You can do this if the classes all have a common interface • You may want to be able to create objects, without being dependent on the kind of object • A factory method can create instances of different classes, depending (say) on its parameters

  49. FACTORY DESIGN PATTERN • Example: public Image createImage (String ext) { if (ext.equals("gif")) return new GIFImage(); if (ext.equals("jpg")) return new JPEGImage(); ...} Note that it is not known beforehand what KIND of objectwill be created.

  50. The Immutable Design Pattern • There are many benefits to objects that cannot be changed after they have been created • Such objects are called immutable • Objects that refer to an immutable object never have to worry about whether that object has been changed • Immutable objects are thread-safe—this is a significant efficiency concern, because synchronization is expensive