本篇同步发文于个人网站: Moving Features
This article references the chapter 8 " Moving Features " of Refactoring: Improving the Design of Existing Code (2nd Edition). Author had highlighted many important refactorings in this chapter.
I use .NET C# to practice with these refactorings and upload to Github.
(Photo from Pixabay: https://pixabay.com/illustrations/plumber-repair-tools-pipe-plunger-4427401/https://pixabay.com/illustrations/moving-boxes-mover-moving-truck-3671446/ )
Move Function
Tips
If a nested function of a outer function may be used for other situations, move this nested function to a general scope.If a function of a class is better for other class, move this function into the target class.Examples:
Moving a Nested Function to Top LevelMoving between ClassesGithub
Move Field
Tips
If other structures are modified after one field is modified, we should move this field into a central structure.Field should be encapsulated, it means that we add get/set accessors to encapsulate fields to avoid "Bare" record.Examples:
A simple exampleMoving to a Shared ObjectGithub
Move Statements into Function
Tips
If some statement repeatably works on many places, we should move it into a function.Examples:
A simple exampleGithub
Move Statements into Callers
Tips
If some statement are changed by callers in a function, we should extract it to each caller.Examples:
Just use the Move Statements into Function example from end to startReplace Inline Code with Function Call
Tips
If some inline code has been implements in some function, replace it with the function.A good naming function shows what the inline code outputs without understanding the implementationExamples:
// before refactoringbool hasMyFavoriteFruit = false;foreach(var fruit in basket){ if(fruit == "Apple") { hasMyFavoriteFruit = true; }}// after refactoringbool hasMyFavoriteFruit = basket.Contains("Apple");
Slide Statements
Tips
Some variable declarations are placed together on the top of scope, but author recommends that he declares variable when only first time he uses it.Some statement has side-effect. If we slide it without test, it may cause the error.We can implement the statement (function) by using Command/Query separation pattern to avoid the side-effect.This refactoring focuses on the change of the state. When we slide statement, Split Variable is a good method.Examples:
Sliding with Conditionals
// before refactoringResponse result = null;if(connection.Status == Status.OK){ result = CreateSuccessMessage(); connectionResponses.Add(result);}else{ result = CreateFailsMessage(); connectionResponses.Add(result);}return result;// after refactoringResponse result = null;if(connection.Status == Status.OK){ result = CreateSuccessMessage();}else{ result = CreateFailsMessage();}connectionResponses.Add(result);return result;
Split Loop
Tips
If a loop contains many independent works, split them into their own loop scope.We use Move Statement to move related variable declaration near by the new loop.Split loop can be extracted as a function.Replace Loop with Pipeline is a better implementation.Examples:
A simple exampleGithub
Replace Loop with Pipeline
Tips
Collection Pipeline is a modern pattern. A pipeline receives a collection and process it with some operations and outputs a new collection.JavaScript has map/filter/... pipeline functions, C# has LINQ (select/where...).Pipeline increases the code readability.Examples:
A simple exampleGithub
Remove Dead Code
Tips
If some code is not used ever, remove it to avoid confusing you/your team members.Version control can manage all code history. Make the good use of it.Conclusion
This chapter introduces me how to move the code logic greatly. In my early coding job, I used to write long logic function. And this function was gradually hard maintainable. I learned some like Moving Features skills to enhance the code but it still was not completed. I have grown up to write better code when I study this refactoring chapter. If you want to learn detailed motivation and mechanics, study the chapter 8 " Moving Features " of Refactoring: Improving the Design of Existing Code (2nd Edition). and it improves our programmer's ability.