Manifesto of the Net Programmer or a short synopsis of the book "Pure Code" of Robert Martin
This article is a synopsis of the book "Pure Code" of Robert Martin and my understanding of how pure code should be. There are no sections about testing, TDD, what architecture should be, etc. Here everything is just about what the Pure Code should be.
Yes, it's possible that the topic of Clean Code is already jaded, but nevertheless, not everyone is familiar with it, and moreover, I did not meet the analogues of the content contained in my article.
There is no true path and solution. There is one that is best suited for a specific task.
When solving the problem, try to reproduce absolutely all the cases that can affect this task and implement the task taking into account absolutely all cases.
Also, when solving a problem, try to go from the opposite. Understand what results in the end you want to get and compile on this basis the algorithm by which the task will be performed.
Before you send a task to the release - check to see if it works correctly. Are there any mistakes in it? This applies even to those commits that are sent to your branch. The most ideal scenario is one in which no one could find errors in the functionality that you developed.
Always think about how you can make your code easier, cleaner and more readable.
What kind of cases can the task have?
Did I take everything into account?
What can go wrong?
What can be combined?
Is there a similar functionality?
What is there too much?
How to make it easier?
How to make it more readable?
How to make it clearer?
The pure code is
How to write clean and good code? It's like writing a book. First you make a draft and then comb it up to the state in which you would be pleased to read it. Always remember that your code should tell the story of what is happening so that the reader can understand it.
The essence is understood - interface, class, method, variable, object, etc.
The clean code is simple, expressive and aimed at a specific task.
Clean code is easy to read, like prose. If this is not the case, then it should be refactored.
Clean code is easy to change. It should not be rigidly tied to a pile of essences. Any entity can be easily changed.
Clean code is much better reviews. If the review takes place with a huge amount of comments, then it is not clean and it needs to be refactored.
Clean code always looks like it's been working on it for a long time. Whatever ways to improve it you are not looking, you will still come to the fact that this code is the best. Accordingly, the clean code is thought out to the last detail.
The Boy Scout Rule: Leave the parking lot cleaner than it was before you. This is easily shifted to programming. Do you see the dirty code? Make it cleaner until you solve your problem. Do not get carried away by this and if the dirty code is very dirty, then it is worth highlighting a separate task and time for cleaning it.
Do not be afraid to make changes. If you want to do them, then you have a reason, so you will make the code better and cleaner. Especially tests will show whether there are any errors in your code (provided that they generally exist).
Any entity must be responsible for one functional and only for it. And she must perform it well. Single Responsibility.
If the entity responds immediately for two or more actions, then its functionality needs to be divided.
The code should be read from top to bottom.
In a good and competent architecture, making changes is costless and effortless.
Delete the dead code. A dead code is a code that will not be called under any circumstances or code that is not used anywhere.
Names and separations
Use clear and convenient names for any entities. They should describe why this entity exists, what it does and how it is used.
Do not be afraid to waste time choosing the best and most understandable name. You will win in the future when working or reading this code.
If the name of the entity does not correspond to its functional or the name does not understand what the entity does, then it should be renamed to the most understandable name. If this can not be done, then it means something is wrong with its function and it needs to be refactored.
The entity that has the name "And", "With" - violates Single Responsibility. The functional of such an entity is worth sharing. But this rule is sometimes neglected.
Unclear texts, lines should be put into variables and give them clear names.
The method names must contain a verb that describes what this method does and the keyword with which the method works. If there is no verb in the name of the method, then this entity should not be a method or it should be given the correct name.
It is necessary to avoid identical names for two different purposes.
If the entity has a name similar to another entity, then most likely their functionality is very similar and need to be combined? If not, then their names should be changed so that they are not similar.
If you mentally rename the entity, when you read the code, so that you understand its functional more clearly, then rename it into this mental name.
Choose one word for one concept. It will be difficult to understand the functional when you have fetch, retrieve and get in the names. Let it be better to get everywhere.
A long and clear name is better than a short, but incomprehensible.
Functions must be short and compact.
Functions must be very short and very compact.
An approximate maximum of 20 lines and 150 characters in one line, if not crawls, then you need to separate.
The function must perform only one operation.
She should do it well and she should not do anything else.
If the function performs only those actions that are on the same level of abstraction, then the function performs one operation.
To determine if the function performs more than one operation, try to extract from it another function that will not be a simple reformulation of the implementation.
Any conditional operators with long choices through switch-case, if-else must be separated or combined without duplication, perhaps into classes with implementations, and the choice of implementation passed to the base class, factory or someone else.
If, else, while, etc. must contain a call to one function. So it will be more readable, understandable and simpler.
The ideal number of input arguments for the function is 0. If there are more than three input arguments, it is worthwhile to think about how to get rid of them, for example, to create a class for these arguments.
The more input arguments, the harder the function is understood.
Function in which the argument-flag is transmitted, on which the function of the function depends, indicates that the function performs more than one operation. Such functions should be divided into two and call them a level higher.
A function that changes the input argument must give a reference to the changed object, and not just change it without a return.
String transform (String text)
If the function should change the input argument, then let it change the state of its owner object.
If the input argument of the function does not need to change (and is used later in the code), then copy the value of the argument and work with the copy inside the function.
Instead of return null it's better to use an empty object -
Collection.empty () or the null object is
EmptyObject () .
Always try to use non-static functions. If this is not possible, then use static.
If there is code that must follow one after another, then pass the results of the first function to the second, so that someone does not change the sequence of calls.
Use polymorphism instead of if /else or switch /case or when.
Avoid negative conditions.
- Do not use comments if you can use a function or a variable instead.
- Do not comment on bad code - rewrite it. It is not necessary to explain what happens in bad code, it is better to make it explicit and understandable.
- Comments can be used to convey some information, a warning about the consequences, but not to explain how the code works.
- Use TODO and FIXME.
//region REGIONNAME //endregion REGIONNAMEAnd if you use, then think about whether you can divide the region into entities.
- Document the code that is complex, but clean.
- Do not leave the old commented code. You can find it in the history of commits, if necessary.
- Comments should be concise and understandable. There should not be a lot of information in comments with information. Everything should be brief and on the case.
Formatting and rules
- Observe the codestyle adopted on the project.
- Observe the rules adopted in the team.
- If you follow the formatting and codestyle code will be read easier and better. It's not for nothing that the book is given to the editorial office, before it is published.
- You need to have automatic tools that will format the code for you.
- The file with the source code should be like a newspaper article. There is a title, a brief description in the form of parameters and content in the form of functions. If this is not the case, then you should change the formatting.
- Entities that are related to each other must be near, for example, in one package, so that it's easier to navigate through the code.
- The variables (fields) of the class must be at the top of the class.
- The method variables must be closer to their place of use.
- The functions must be in the order of the call. If one calls another, then the calling function must be above the called function. On the other hand, private functions of a lower level can be at the bottom of the file and do not interfere with the understanding of high-level code. But I prefer the first method.
Objects and data structures
- You must work with abstractions so that the implementation can be easily changed.
- You should work with abstractions, because the client using the functional does not need to know about the details of the implementation, he needs to know what implementation to use in which case.
- You must provide an API that you should work with and hide the implementation details, structure. So it will be easier to work with such entities and add new types of behaviors, functional and implementations.
- DTO - Data Transfer Object. A class that contains only data and no functionality. It is necessary in order to transmit some data. An object of this class must be immutable.
- Classes must be compact.
- Classes should be even more compact.
- The class name should describe its responsibility. From here you can calculate the size of the class.
- The class functional must match and fit into the class name.
- Divide the connectedness into small classes. Hard and abundant cohesion should not be - this complicates the support and development of the project.
- Remember about Single Responsibility. The entity must have one and only one reason for the change.
- Observe encapsulation. The weakening of encapsulation should always be the last measure.
- Usually we declare variables and auxiliary functions private, but sometimes they need to be declared protected and have the ability to access it from the test.
- If a group of functions refers to a specific functional, then this group of functions can and should be allocated to a separate class and use its instance.
- Use Exceptions instead of returning error codes.
- Error handling is one operation. If the function has the keyword
try, then after the blocks
catch /finallynothing else in the function should not be.
If you have an enum that lists errors, then it's better to get rid of it and use exceptions instead.
Use unchecked exceptions to explicitly point to a place in which there are problems. Such errors do not need to be caught, instead you need to write the code so that this error never was.
BeforeYou should have enough information along with throwing an exception so that later your users of the code can understand what really happened.
Instead of conditional operators with error handling, it is better to throw exceptions and process them.
Do not pass null anywhere. Try to avoid this as much as possible.
Error handling is a separate task and does not apply to the basic logic of the program.
We always use any libraries that most often give us too wide, too little functionality or conflict with the expected functionality, which makes the code dirty in its final use. You can avoid this by simply applying patterns such as Decorator, Adapter, Facade, or others.
There are situations when you need to work with functionality that is in development or has not yet been adapted for use in production code. In this case, it is worthwhile to imagine what you expect from the library /this functional and write your interface or create an entity with which you will work in your project the way you need it. When the library is completed and becomes stable, you adapt it to your ready-made structures and use the ready-made functionality.
This article presents only recommendations for writing the Clean Code. Of course, they can be neglected. You only need to understand that any of your decisions should have arguments in favor of him.
It may be interesting
Thankyou for sharing the data which is beneficial for me and others likewise to see.Gulf Coast Western Reviews
Positive site, where did u come up with the information on this posting?I have read a few of the articles on your website now, and I really like your style. Thanks a million and please keep up the effective work.GSM Solutions