Refactoring IIBooksDesign Patterns and RefactoringUML review IUML review IIBad smellsAn exampleUsing my “Command” patternDuplicated code IDuplicated code IIDuplicated code IIIDuplicated code IVThe Template MethodBig fish and little fishThe move() methodThe Fish refactoringTo be continued...Jan 14, 2019Refactoring IIBooksDesign Patterns is the classic book by Erich Gamma, Richard Helm, Ralph Johnson, and John VlissidesBasically a catalog of program organizationsReading it is rather like reading a dictionaryAlthough equally applicable to Java, the examples are in C++AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis by William J. Brown, Raphael C. Malveau, Hays W. "Skip" McCormick, Thomas J. MowbrayDescribes bad patterns and how to fix themMore fun to readRefactoring: Improving the Design of Existing Code by Martin Fowler, with contributions from Kent Beck and othersVery clear, plenty of useful ideas, very readableMuch of this lecture will be based on this bookDesign Patterns and RefactoringDesign Patterns describe good solutions to common (or at least, not extremely rare) design problemsDesign Patterns are always specified in UMLModel-View-Controller is a very common Design PatternAn Antipattern is a common, but poor, Design PatternAntipatterns can be refactored into better designsRefactoring is rearranging existing code while maintaining the same functionalityRefactoring is usually done in terms of applying some Design PatternUML review IKey:+ means public visibility# means protected visibility- means private visibility<blank> means default (package) visibilitystatic variables are underlinedName of the classVariables [optional]MethodsCardcardId:int-copy:boolean=false«constructor» Card(int id)+isKind(desiredKind:int)+isSharable():boolean+toString():StringExample:UML review IIABClass Bextendsclass ACD1..4Class Ccontains 1 to 4 objectsof class DFactoryProductcreatesOther kinds ofrelationsABClass Bimplementsinterface ABad smellsWhere did this term come from?“If it stinks, change it.” --Grandma Beck, discussing child-rearing philosophyThe basic idea is that there are things in code that cause problemsDuplicated codeLong methodsEtc.A common reason for refactoring is that you need to add features that don’t fit well with the existing designAny time you change working code, you run the risk of breaking itA good test suite makes refactoring much easier and saferAn exampleSome time ago I was working on code to evaluate expressionsExpressions can be parsed into a tree structureNow what?You could walk the tree and, at each node, use a switch statement to do the right thingI “discovered” a better solution+2 *5 xTree for 2 + 5 * xCommandlhs:Commandrhs:Commandvalue:intevaluate():int0..2Using my “Command” patternclass Add extends Command { int evaluate( ) { int v1 = lhs.evaluate().value; int v2 = rhs.evaluate().value; value = v1 + v2; return value; }}To evaluate the entire tree, evaluate the root nodeThis is just a rough description; there are a lot of other details to considerSome operands are unaryYou have to look up the values of variablesEtc.Commandlhs:Commandrhs:Commandvalue:intevaluate():int0..2Duplicated code IIf the same code fragment occurs in more than one place within a single class, you can use Extract MethodTurn the fragment into a method whose name explains the purpose of the methodAny local variables that the method requires can be passed as parameters (if there aren’t too many of them!)If the method changes a local variable, see whether it makes sense to return that as the value of the method (possibly changing the name of the method to indicate this)If the method changes two or more variables, you need other refactorings to fix this problemDuplicated code IIIf the same code fragment occurs in sibling classes, you can use Extract Method in both classes, then use Pull Up MethodUse ExtractMethod in each classBe sure the code is identicalIf necessary, adjust the method signatures to be identicalCopy the extracted method to the common superclassDelete one subclass methodCompile and testDelete the other subclass methodCompile and testDuplicated code IIIIf the same code fragment occurs in unrelated classes, you can use Extract Method in one class, then:Use this class as a component in the other class, orInvoke the method from the other class, or Move the method to a third class and refer to it from both of the original classesIn any case, you need to decide where the method makes most sense, and put it thereDuplicated code IVIf almost the same code fragment occurs in sibling classes, use Extract Method to separate the similar bits from the different bits, and use Form Template MethodI’ve done this one recently, and it makes a good exampleThe Template MethodTemplate Methods lead to an inverted control structureA superclass calls methods in its subclass Template methods are so fundamental that they can be found in almost every abstract classTemplate Method uses inheritance A similar pattern, Strategy Pattern, uses delegation rather than inheritanceBig fish and little fishThe scenario: “big fish” and “little fish” move around in an “ocean”Fish move about randomlyA big fish can move to where a little fish is (and eat it)A little fish will not move to where a big fish isBigFishmove()Fish<<abstract>>move()LittleFishmove()The move() methodGeneral 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}My solution:Extract the check on whether it’s ok to moveIn the Fish class, put the actual (template) move() methodCreate an abstract okToMove() method in the Fish classImplement okToMove() in each subclassThe Fish refactoringBigFishmove()Fish<<abstract>>move()LittleFishmove()BigFishokToMove(locn):booleanFishmove()<<abstract>>okToMove(locn):booleanBigFishokToMove(locn):booleanNote how this works: When a BigFish tries to move, it uses the move() method in FishBut the move() method in Fish uses the okToMove(locn) method in BigFishAnd similarly for LittleFishTo be
View Full Document