Refactoring is an extremely important part of the development process. Writing the code “that works” is not the key to a productive application. Refactoring makes it possible to bring the code into the proper form, which will further allow this code to be easily read, reused, maintained and expanded the system itself.
Design
The beginning of a good code is always design. Programmers who do not know how to calm the passion for writing code, thus omitting the design, usually write quickly, but not qualitatively. I know this because I myself had the same problem. Design provides an opportunity to look at the system, which is still not actually present, to think over the correct structure of the application and data, see the subtleties, risks, think about performance and security. In this case, design is not only the prerogative of the start of the project. Design is an integral part when developing any “Feature”.
You can start designing very easily. Always keep a notebook and several colors of pens in your workplace. Before writing the code, draw a diagram - how the application will work as a whole, UML class diagram (think as much as possible with the minimum number of classes, achieve maximum results), database structure (optimize the database before it is created, think what queries you should have will run to your database, think over the indices, of course, normalize your data model).
For the same purpose, a simple program for designing
starUML will do . Its disadvantage is that it is impossible to establish the power of relations normally (multiplicity), but the interface itself is very convenient.
')
It is necessary to design even so that later you do not have to refactor structural errors, and even worse to rewrite the entire module at all.
A few principles that you need to know when designing your “Feature” classes:
1. SOLID (single responsibility, open-closed, Liskov substitution, interface segregation and dependency inversion)
This is the foundation of class design. If you are not familiar with SOLID,
you can find it here .
2. DRY (do not repeat yourself)
Repeated functionality makes the application cumbersome, and its support is more expensive and inconvenient. This applies to both modules and small code fragments.
For example:
- Instead of using three lines of code in several places, you can put them in a function and use just one line of code - a function call.
- Instead of using the progress50 () function, it is better to use a more abstract progress ($ percent).
- Prefer external dependencies between modules, internal (DI), which makes the module more flexible and allows you to use it in several places.
3. KISS (keep it simple, stup ...)
The simpler your solution for a complex task, the more perfect it is, just as this rule works in the opposite direction. To learn how to make simple decisions, you need to learn how to divide your task into very small subtasks. Moving from smaller to bigger. Subsequently, we get the result of a complex task.
For example:
You need to write a class to generate an Excel report from your database. You need to divide the entire report into parts: setting table headers, outputting statistical data to a document, outputting a document footer, creating a chart. Some parts of the functionality can be taken out into separate classes, which will make it possible to reuse them.
Code style
Code style refactoring does not affect application performance at all. However, it gives an advantage to its readability and support. Another programmer should easily read your code, without understanding the implementation of details, and this, of course, saves time and money.
Standard style code (and not only) PSR (PHP Standards Recommendations),
here you can find . The content is in English, as English makes it clearer to understand the degree of application of one or another rule (“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, "RECOMMENDED", "MAY", and "OPTIONAL").
A few comments that the author found important :
1. Check out PHPDOC for writing comments on your code.
2. The best comment is a properly named class, method, parameter, or variable.
3. Use the PHPMD, PHPCS utilities, their use is wider than just to identify inconsistencies in the style of the code. Here is the documentation:
PHPMD ,
PHPCS .
4. Use an advanced IDE.
Pure refactoring
Very simple axiom - only the code that has undergone refactoring should fall on the production. Sometimes after development, you yourself do refactoring, which is not even bad (for example, development through testing generally includes refactoring, as an obligatory step, since the “working code” is originally written, and then “clean”), but in order to the code was really high-quality, it must pass a code-review by another programmer. If the project allows you to allocate time to check the code, then on such a project you will learn to write code cleaner and cleaner, which later will lead to automatic writing of high-quality code.
I remember working for one company, and checking my code was done by a person who could not always restrain his emotions, which is why everyone heard about my non-clean code in open space. Therefore, I had to learn to write high-quality code very quickly to avoid such cases.
Let's return to the topic. In this part of the article I would like to give some practical approaches to refactoring, which I use myself.
1. Long methods (it is better to divide the functionality into several methods).
2. Bulky classes (your class must perform one functional task on your system).
3. Unclear class structure (methods in chaotic order, constructor in the middle of a class, instead of constants — magic values in the code — the class should easily reflect what it does in the correct sequence).
4. Too many parameters in the method (some calculations can be made inside the method, using internal constants, values obtained from attributes and getters).
5. Classes containing the same variables and methods. The problem can be solved through the creation of an additional class).
6. Difficult to read IF (expression can be put into a separate variable and divided into logical parts, which can also be put into variables, if there are a lot of checks for null, then it is best to use NullObject - the number of checks will be significantly reduced).
7. Bulky SWITH (take out in a separate method).
8. The use of inheritance due to the same methods and properties, in different entities in essence (the cat and the chair have legs, but they cannot be grouped into the category “animals”).
9. Too many small classes to perform a single task, which are then harder to maintain.
10. Too complex functionality in one class, which can be divided into several classes.
11. The class does too little to keep it in the system.
12. “Dead Code” - it should be deleted.
13. The unused structures of the classes that you designed for the future, but they were not useful - these are better to delete.
14. Class methods are used more in another class, but are not used at all or less often (it is worth moving the method to the class where it is more used).
15. The call chain is too long ($ a-> b () -> c () -> d () -> e ()), in this case it is worth creating additional methods.
16. A class containing only one method that creates another class. (This class should be used wisely, for example, for the Proxy pattern, otherwise this class only increases the time and resource to support the project).
17. Too many actions in the constructor. (The constructor should only set properties of the class, if other classes are created in the constructor, some calculations occur, this makes it difficult to understand, you have to understand the implementation. To create an object and perform some actions, add the create static method ($ param1, ...), which will create an instance of the class with additional actions on it, this method can be called more appropriate for what it will still do).
Bibliography
»
Source Making»
PSR»
UML