Code examples for Refactoring Legacy Code Tutorial.
See the checklist below for the complete list of refactorings applied in the tutorial.
- Run
XMLToJsonTestwith coverage. - Rename variable
urltourlToTOC- enables better understanding of the variable's purpose. - Remove dead/commented code - improves code clarity and maintainability.
- Remove the cast to Element - unnecessary and clutters the code.
- Convert wrapper type
Booleanto primitiveboolean- avoids unnecessary object creation and potential null pointer exceptions. - Decompose conditional - extract conditional code to clearly named method.
- Remove else branch with empty body - simplifies the code by removing unnecessary branches.
- Remove unnecessary
continuestatement - enhances code readability. - Use
isEmpty()to check whether the collection is empty or not. - Remove unnecessary
mainmethod - cleans up the code by removing unused entry points. - Replace
equals("")withisEmpty()- improves readability and performance.
- Simplify
hasChildrenvariable assignment by removing if else statements - reduces nesting and improves readability. - Inline
hasChildrenvariable - eliminates unnecessary variable and simplifies the code. - Extract method
getNodeto reduce complexity before start iterating - breaks down large methods into smaller, more manageable pieces. - Extract method
processElementto handle element processing - Useoption+Up Arrowto expand your selection. - Extract method
closeJsonto handle JSON closing logic - Extract method
getJsonForDocumentto inject a Document instead of obtaining it inside the method.
Introduce further refactorings to improve testability and maintainability.
Replace Function with Command aka Replace Method with Method Object encapsulates behavior in command objects for better testability.
- Extract method
toJsonString(String, Element)to convert a Document element to JSON string. - Create class
DocumentElementto represent document elements - encapsulates related data and behavior. - Add
DocumentElementas parameter totoJsonStringmethod. - Inline method
hasChildren- make the code accessible fromtoJsonStringmethod. - Convert
toJsonStringmethod to an instance method ofDocumentElement- improve encapsulation and support polymorphism. - Extract method
hasChildreninDocumentElementclass. - Create constructor
DocumentElement(String)- pass arguments to the command on the constructor. - Use
xPathStringfield intoJsonStringmethod - utilize instance fields for better encapsulation. - Safe delete
xPathStringparameter fromtoJsonStringmethod - remove unused parameters to clean up the method signature. - Add
Elementparameter toDocumentElementconstructor - ensure all necessary data is provided at instantiation. - Use
elementfield intoJsonStringmethod - utilize instance fields for better encapsulation. - Safe delete
elementparameter fromtoJsonStringmethod - further clean up the method signature. - Introduce field
jsonStringto store the result oftoJsonStringmethod - maintain state within the command object. - Introduce field
elementNameto store the element name - move the function state into the command object. - Introduce field
attributesto store the element attributes - move the function state into the command object. - Introduce field
titleto store the element title - move the function state into the command object. - Introduce field
fileto store the element filename - move the function state into the command object. - Extract method
processDocAttributesinDocumentElementclass - break downtoJsonStringmethods into smaller pieces. - Extract method
addStateClosedinDocumentElementclass - compose method to handle state closing logic. - Extract method
closeElementinDocumentElementclass - compose method to handle element closing logic. - Extract method
processFolderAttributesinDocumentElementclass - break downtoJsonStringmethods into smaller pieces.
Replace Conditional with Polymorphism uses polymorphism to handle conditional logic.
- Extract method
processElement()inDocumentElementclass - extract conditional statement into its own method. - Encapsulate variable
elementName- self-encapsulate the type code. - Replace Constructor with Factory Function aka Replace Constructor with Factory Method - use factory methods to create an instance of
DocumentElement. - Create
DocElementsubclass and add selector logic fordoctype code value in the factory method. - Override the type code getter in
DocElementclass to return the literal type code value. - Create
FolderElementsubclass and add selector logic forfoldertype code value in the factory method. - Override the type code getter in
FolderElementclass to return the literal type code. - Remove type code field
elementNamefromDocumentElementclass. - Add default branch in the factory method to handle unexpected type code values.
- Make
getElementNamean abstract method andDocumentElementan abstract class. - Override
processElementmethod inDocElementclass. Copy the relevant logic from the conditional statement. - Push Down Method
processDocAttributestoDocElementclass - move method to the subclass where it's relevant. - Rename
processDocAttributesmethod inDocElementclass toprocessAttributes- generalize method name for better readability. - Push Down Method
addStateClosedtoDocElementclass - move method to the subclass where it's relevant. - Push Down Method
hasChildrentoDocElementclass - move method to the subclass where it's relevant. - Override
processElementmethod inFolderElementclass. Copy the relevant logic from the conditional statement. - Push Down Method
processFolderAttributestoFolderElementclass - move method to the subclass where it's relevant. - Rename
processFolderAttributesmethod inFolderElementclass toprocessAttributes- generalize method name for better readability. - Declare
processElementmethod inDocumentElementclass as abstract - enforce implementation in subclasses. - Safe delete
getElementNamemethod fromDocumentElementclass and its subclasses - clean up unused methods.