MartinFowler's book RefactoringImprovingTheDesignOfExistingCode may do for refactoring what DesignPatterns did for design: create a language (a system of words) that we can use to express our refactoring thoughts.
The catalog from the book, with additions, is at http://www.refactoring.com/catalog/.
Organizing Classes:
- RenameClass (including RenameClassInVbClassic)
Composing Methods:
- ExtractMethod (= ComposedMethod from SmalltalkBestPracticePatterns by KentBeck)
- ComposeMethod
- InlineMethod
- RemoveAssignmentsToParameters
- ReplaceMethodWithMethodObject
- MovingFeaturesBetweenObjects
- MoveMethod
- MoveField
- ExtractClass
- InlineClass
- HideDelegate
- RemoveMiddleMan
- IntroduceForeignMethod
- IntroduceLocalExtension
Within Methods:
- InlineTemp
- ReplaceTempWithQuery
- IntroduceExplainingVariable
- SplitTemporaryVariable
- SubstituteAlgorithm
- RefactorIntroduceWith (new)
- RefactorEliminateWith (new)
- RefactorMatchLoopToUsage (new)
- RefactorNegateIf, RefactorDefaultOrElse, ReverseConditional (new)
- RefactorRenestBlocks (new)
- HugeCaseStatements (new) - replaces if/elseif/elseif... with Java trick that uses metadata
Organizing Data:
- SelfEncapsulateField
- ReplaceDataValueWithObject
- ChangeValueToReference
- ChangeReferenceToValue
- ReplaceArrayWithObject
- DuplicateObservedData
- ChangeUnidirectionalAssociationToBidirectional
- ChangeBidirectionalAssociationToUnidirectional
- ReplaceMagicNumberWithSymbolicConstant (see MagicNumber for more examples)
- EncapsulateField
- EncapsulateCollection
- ReplaceRecordWithDataClass (VisualBasic: VbClassicRefactorTypeToClass, C++: CppRefactorStructToClass)
- ReplaceTypeCodeWithClass
- ReplaceTypeCodeWithSubclasses
- ReplaceTypeCodeWithStateStrategy
- ReplaceSubclassWithFields
- SimplifyingConditionalExpressions
- DecomposeConditional
- ConsolidateConditionalExpression
- ConsolidateDuplicateConditionalFragments
- RemoveControlFlag
- ReplaceNestedConditionalWithGuardClauses
- ReplaceConditionalWithPolymorphism
- IntroduceNullObject
- IntroduceAssertion
- ExtendToImplementInterfaces - to abstract a class' interface, when you can't change the class.
- BehaviorToState
- ReplaceRecordedHistoryWithEventNotification
Making Method Calls Simpler:
- RenameMethod
- AddParameter
- RemoveParameter
- SeparateQueryFromModifier
- ParameterizeMethod
- ReplaceParameterWithExplicitMethods
- PreserveWholeObject
- ReplaceParameterWithMethod
- IntroduceParameterObject
- RemoveSettingMethod
- HideMethod
- ReplaceConstructorWithFactoryMethod
- EncapsulateDowncast
- ReplaceErrorCodeWithException
- ReplaceExceptionWithTest
- RefactorReorderParameters
- RefactorParametersToMemberVariables
- RefactorScopedVariableToParameter
Dealing With Generalization:
- PullUpField
- PullUpMethod
- PullUpConstructorBody
- PushDownMethod
- PushDownField
- ExtractSubclass
- ExtractSuperclass
- ExtractInterface
- CollapseHierarchy
- FormTemplateMethod
- ReplaceInheritanceWithDelegation
- ReplaceDelegationWithInheritance
- RefactoringClassToBePolymorphic (new)
- ReplaceCodeWithData
- ReplaceDataWithCode
- IntroduceCodeGenerator
BigRefactorings: (originally described by MartinFowler)
- TeaseApartInheritance
- ConvertProceduralDesignToObjects
- SeparateDomainFromPresentation
- ExtractHierarchy
- RefactorInsertComment
- RefactorReplaceCommentWithTestCase
- NonInvasiveRefactoring
JavaLanguage Specific: (RefactoringIdioms)
- HugeCaseStatements - replaces if/elseif/elseif... with Java trick that uses metadata -- (It's not really a Java trick. Well, okay, it is, but it doesn't have to be. You could keep a Hashtable around with String to Class (or String to Instance if you're using Flyweights and want to save the time it takes to create the class), and use that instead of the Class.forName(). Indeed, when I mention that the code could be optimized for speed, the optimization is to stick the classes in a Hashtable, and check there before creating new ones.)
- ExtractPackage - "A package either has too many classes to be easily understandable or it suffers from the 'Promiscuous packages' smell." -- Gerard M. Davison. See http://www.refactoring.com/catalog/extractPackage.html
- RefactorExtractMethodCallsToAspect
- RefactorExtractExceptionHandlingToAspect
- RefactorConcurrencyControlToAspect
Of course, if you want to see the real dictionary for this language, go buy the book: RefactoringImprovingTheDesignOfExistingCode.
Hear, hear. I've just finished reading the essay-type sections, and I now don't want to design my next application, but instead let the design evolve from the code. Unfortunately, my manager is one of the lots-of-upfront-design types. Oh well, maybe we can strike a compromise in the middle.
Easy: Ensure that you have plenty of unit tests. If the design isn't testable, then file a bug against it (BDUF people probably don't like the idea of untestable things, so they'll fix it). In 6 months time, when the design is hopelessly out of date, you'll have a good case for refactoring: Anyone counting beans will see the cost advantage at that point.