Abstract: Let’s go back to the basic concept of refactoring and think about what kind of refactoring assistance services we need.
The background,
Code refactoring is a term that every developer is familiar with, and it often accompanies the development process. In the long road of program development, iteration and evolution, a casual modification may destroy the original design and structure of the program, resulting in the loss of the code structure, and this loss is cumulative. If it is not found and reconstructed in time, the program will gradually rot or even deteriorate, forming a huge historical debt. Refactoring is like cleaning a house. If we clean every day, we can clean it in 3 minutes, but if we don’t clean it for a month, think about how long it will take to clean it.
Since code refactoring is so important in the development process, how can there not be a corresponding service to support it? Could we develop a broom to help us clean our rooms every day? Or a “robot sweeper” that automatically cleans a room that hasn’t been cleaned in a month?
With that in mind, let’s go back to the basics of refactoring and think about what kind of refactoring assistance services we need.
1. What is refactoring
As described in the book, Refactoring is the process of making changes to code to improve the program’s internal structure without changing the code’s external behavior. Refactoring here has two meanings, a noun meaning and a verb meaning:
Refactoring, n: An adjustment to the internal structure of software to improve its comprehensibility and reduce its modification costs without changing its observable behavior.
Refactoring (verb) : The use of a series of refactoring techniques to adjust the structure of software without changing its observable behavior.
At this point, it should be clear that a good refactoring assistance service should have at least two characteristics: invariance and variation: no change in software observable behavior; Optimize code structure to reduce modification costs and improve understandability.
2. When to refactor (and when to refactor)
Refactoring a question of timing, the industry also has a more intense discussion, some people think that refactoring should be anytime, anywhere, should not be to refactor and, like when I was in to add a new function, repair errors, or review can refactor the code, we call this “development reconstruction”, also some people think that “add new function” and “refactoring” are two hats, When you add new features, you don’t need to modify the existing code. When you refactor, you don’t need to add features. You just need to improve the structure of the program, one thing at a time. Personally, I don’t think these two statements are contradictory, and a good refactoring is a combination of the two.
As shown in the figure above, the red range is what I consider a good refactoring practice.
I think refactoring is appropriate for both new feature development and old version maintenance, but at different levels of granularity. For development-time refactoring, it is more suitable for micro-refactoring in a small range at the personal level. Such refactoring often has a small impact range and is relatively simple, without increasing the difficulty of development, such as atomic refactoring such as “renaming” and “function extraction”. For the reconstruction during maintenance, it is more suitable for the large-scale complex reconstruction at the architectural level, which is usually to solve the technical debt left in the project code and is usually combined with the elimination of the bad taste of the code, such as Feature Envy, Data Clumps, etc. The refactoring of these bad smells is often a combination of a series of refactoring atomic operations. Of course, it’s best to do as much refactoring as possible in the development phase, to minimize the amount of additional code that disrupts the existing design and architecture.
Do we have some deja vu here, which corresponds to the application of “broom” and “sweeping robot” in the actual refactoring work mentioned above?
3. Why are intelligent code refactoring services needed
Those of you who have used modern ides to develop code know that many ides, such as IntelliJ IDEA, come with some form of refactoring, but so far these refactorings have been atomic refactorings such as “rename” and “function extraction” that only partially support the refactoring process. Most of the code, architecture bad smell refactoring is still done by hand, like cleaning a house that hasn’t been cleaned for a month, but you only have a broom. Kent Beck said, “Manual refactoring is still time consuming. It is this simple fact that causes many programs to be reluctant to refactor, even though they know they should, but the cost of refactoring is too high. If refactoring can be made as simple as reformatting code, programmers will be happy to reformat the system design as well. This can have a profound and positive impact on code readability, reusability, and understandability.” That’s why it’s important to have a smart service that can help developers find bad smells in code and architecture and guide them through code refactoring.
2. Refactoring service requirements in the whole Devops process
For code development and release in the continuous delivery process, as shown in the dotted box above, almost every step is related to code quality care or code refactoring.
- Development can be broadly divided into two types: “incremental development” for adding new features and “inventory maintenance” for maintaining old releases. For “incremental development”, coding specification refactoring and atomic refactoring capabilities of refactoring services are needed to help developers improve code quality and development efficiency. For “stock type rectification”, you need to refactor code service architecture, bad taste of inspection, the solution to refactor opportunity digging and recommend ability, and the corresponding reconstruction scheme apart for atomic refactoring capability independently and orthogonal to each other, in the end as an atomic refactoring sequence is recommended for developers, with step by step through the application in the human-computer interaction.
- Sustained release in * *, * * MR access code in the static test need to trigger the recognition of bad taste code, as a kind of incremental testing, main identifying code introduced by the new code and architecture bad taste, and automatically generates a refactoring tasks, lead developer on a refactoring, avoid technical debt accumulation in the code.
- In the process of ** production operation and maintenance, ** needs to conduct regular architecture monitoring and display the corresponding measurement results through the visual graphical interface of the architecture. When a module of the architecture is corrupted to a threshold value, an automatic alarm will be given to prompt the version owner to conduct corresponding reconstruction.
Third, how to assist developers to achieve hierarchical code refactoring
1. What levels of refactoring are involved
Personally, I think reconstruction can be roughly divided into four levels. The relationship between these levels can be seen from the figure above, which is not a bottom-up relationship, but some overlap and some differences between them. In terms of the reconstruction itself, the higher-level reconstruction operation is more non-deterministic and more business-oriented, while the lower-level reconstruction operation is more deterministic and more technical. From the perspective of intelligent reconstruction service, the higher the level, the more detection ability, and the lower the level, the more pure reconstruction ability. Let’s take a look at the characteristics and similarities of refactoring at different levels from the bottom up.
Atomic refactoring: Atomic refactoring was mentioned above, but what exactly is atomic refactoring? As the name implies, non-separable refactoring operations, such as rename, move, delete and other refactoring operations, these refactoring operations are completely deterministic, for example, I want to extract a piece of code to form a new method, whether it can be extracted and what can be extracted are completely determined. These refactoring operations are at the bottom of the refactoring because of their non-divisibility.
Coding specification reconstruction: For those of you who may be unfamiliar with this level of refactoring, it’s really refactoring based on norms and rules, usually involving what we call microrefactoring, such as renaming identifiers that violate naming styles, or safe refactoring to remove useless code, etc. And the refactoring operation of this layer can be completely realized by calling 1 atomic refactoring of the lower layer. Because these refactorings are rules-based, the results are relatively deterministic.
Code bad taste refactoring: Code bad smell also includes architecture bad smell, such as Feature Envy and God Class. The purpose of these hierarchical reconstructions is to eliminate the corresponding code bad smell, so they are relatively more complex. The completion of a reconstruction often calls multiple atomic reconstructions at the lower level, such as the reconstruction of God Class. At least one Extract Class atomic refactoring is required. At the same time, the uncertainty of this layer of refactoring is also higher. The refactoring of a bad taste of code can be eliminated by many means.
Bad taste of design pattern reconstruction: This layer of reconstruction should belong to the reconstruction of the top of the pyramid, because it involves a wide range, more inclined to the understanding and prediction of the business, from concrete to abstract, it seems a little illusory. There are 7 bad smells and 11 principles in design patterns. At present, there is not much research on this kind of problem detection and reconfiguration either in academia or industry.
2. Application of intelligent reconstruction service at different levels
Combined with the requirements of refactoring service under Devops and the four levels of refactoring in the figure above, we can basically see which stage of the development workflow the refactoring capability of different levels of intelligent refactoring service is mainly used. Atomic refactoring, because of its deterministic and business-independent nature, is best suited to be integrated into the IDE as a plug-in and invoked by developers doing incremental development. For code specification reconstruction, it is suitable to be integrated into IDE plug-in together with atomic reconstruction to automatically and quickly identify the code that violates specific rules during the development process and assist developers in reconstruction; For code bad taste refactoring, it is suitable to intercept problems during the entrance control phase of continuous release and guide developers back to the IDE for intelligent code refactoring; For the reconstruction of bad taste of design pattern, because it involves business understanding and prediction, it is more suitable for production operation and maintenance. Combining version evolution and iteration history, the prediction of architecture corruption and the corresponding reconstruction scheme are recommended.
3. Building-block refactoring applications
Since the upper level refactoring can be translated into the lowest level atomic refactoring, how can this transformation be expressed? The table lists several common refactoring atomic operations, each of which can be expressed as a function. For example, the Move Method function is called Move Method, and we specify its behavior with three parameters: Source (type), Target (type of Target), and (Method to Move). With this information, we can specify a Move Method atomic refactoring. For any complex reconstruction, it can be expressed as the following form of atomic reconstruction sequence, that is, a series of atomic reconstruction combination.
Just like building blocks, any upper refactoring can be done by combining the underlying atomic refactoring in the same way that building blocks are done.
4. Refactoring service design principles
Refactoring services, like many development services, are designed with the ultimate goal of improving user development efficiency and code quality, and if neither is guaranteed, the service will be consigned to the garbage heap forever. From our practical experience in Huawei, we have summarized the following principles:
Full user interaction: Classic refactoring work process as a “small step forward, readily available, can be stopped at any time, at any time the fallback”, every step small step change means that the possibility of error is greatly reduced, should follow the process, to be without tools and frequent user interaction, to guide the user to complete complex code refactoring step by step, every process to be available at any time, can be stopped at any time, at any time can back.
Friendly interface for refactoring: Code refactoring is similar to automatic code repair, but involves a wider scope than automatic code repair. How to let users better express the intention of refactoring and see the impact of refactoring on the original code architecture is very important. There are a lot of innovations in this part.
Personalized user configuration: levels of refactoring can often have a different execution path, according to the code project is different, different business scenarios, the same kind of bad taste reconstruction implementation also may be different, to the user as the center, according to different business, different users are given the refactoring of personalized, customized solutions, this part is just AI area.
Deep integration of Devops services: Any development service without Devops is an isolated scatter that cannot be used smoothly In the development process. If we can integrate the refactoring service into the IDE, code review, code entry, and validation release, we can make the refactoring tool Build In a trusted development process. Make refactoring services readily available.
Efficiency: Especially with IDE refactoring analysis services, if the analysis process takes too long, programmers will probably not use these refactoring services, preferring to refactor manually.
Click to follow, the first time to learn about Huawei cloud fresh technology ~