
Code in the style of "dump stream of consciousness"
Some time ago, in one of my articles, I described the concept of clay architecture . In continuation, I would like to describe one of the most common "programming styles", which, unfortunately, is very common among young and inexperienced specialists.
So, let's imagine that the programmer is faced with the task of writing a new module or adding some functionality to an existing system. What will an experienced specialist do? He pours himself Chinese tea, leans back in his chair, takes a pencil and begins to think. He will draw the structure of the module, think over the entities, interfaces and the interaction between them, go down to the level of specific methods, probably write unit tests on the interfaces. Only then will he begin to fill the existing structure with code (or delegate this task to a dozen Hindu coders).
Now let's see what a typical junior will do in this case. There is a problem - it must be solved. They were so taught at universities. Many of them are still under the influence of the marginal slogan “write code, ## dy!”. So, he pours himself instant coffee, puts on headphones with something tougher and louder and goes into the stream for a couple of hours.
All would be nothing. I have nothing against coffee, headphones, or flow conditions. Moreover, this is usually the most efficient and often the only way to write good code. But we are considering a typical case of a young and inexperienced programmer, so let's look at the results.
Firstly, the functionality is implemented. It works on most cases and looks quite satisfactory. The first thing I want to do is to be glad that the young specialist coped with the task so quickly, praise him and give the next one. But try a peek into the code. You will immediately understand why the fragment was implemented so quickly. And it will be scary.
Here is a code that I usually call a “dump of consciousness stream” . I call the code just like that, because it is written in a single block, without trying to realize it, without trying to return and change something. Below I will list its main characteristics.
Firstly, the code usually consists of one long, very long method. In it, for example, the connection to the database can be initialized sequentially, the desired request is formed, data is received, processed, and (let it be a webdev) HTML is formed for the final presentation. The author writes about what he is thinking at the moment, he is completely in the stream and focused on solving the problem. His consciousness gradually solves the problem and these steps are immediately reflected in the code.
Secondly, this code is usually filled with commented out lines and pieces that are no longer needed, which it is a pity to throw out and do not need to be left.
Thirdly, usually in this code only the main use cases, standard conditions and branches are processed. With a slight deviation from the standard user behavior, the code mercilessly crashes and crashes with unhandled exceptions.
In part, I wrote about this a little higher, but there are still a fairly large number of factors that need to be said.
The biggest evil from such a code is the absolute impossibility of accompanying it . Indeed, in a few days, not only the “man from the street”, but the author himself will not be able to understand what is happening inside this piece, and for what this branching is responsible. Obviously, programmers, including the author, will not only be reluctant to support such code, but also extremely inefficient.
By the way, this will affect not only the goals of the project, dragging out deadlines and lowering quality , which will undoubtedly upset PMa. Working with such code will seriously undermine motivation.teams from two directions at once, depriving the programmer of his favorite aspects of his work: “I am doing something cool and interesting” and “I am doing an excellent job.”
Another of the sick and unpleasant properties of the “dump of consciousness stream” is that the problems are not immediately visible, since at first glance “everything works”. Very often, testing such a code (of course, by the principle of a black box), the tester encounters bugs that are very difficult to reproduce . Usually they arise due to the intertwined, completely devoid of the structure of the mass of calls and the implicit "leads" associated with it, when one piece of code in a completely amazing way affects the other.
Thus, a testing specialist is added to the “victims” piggy bank to the programmer and project manager already existing there. And in conclusion, in order to assemble a complete project team under this leaky umbrella, we add that the product manager (or the customer in case of custom development) cannot effectively add new features to the product, and the analyst has no idea whether it is possible to make a minimal change , and whether he will hear sky-high dates (or even obscene expressions) from programmers for a simple sentence "to slightly change the operation of the search filter."
The conclusion is simple: a “dump” is an evil that must be fought.
So that this article is not too theoretical, I’ll try to give some tips on how to do this, which I put into practice in my company.
The first and most important thing to understand when you come across this code is “this is normal . ”
If you have not yet begun to struggle with “dumps” (and your predecessor did not do this), then most likely you have several programmers in your team who use this approach, absolutely sincerely believing that they are doing everything right.
It is likely that newcomers taken to your team directly from the student bench also abuse “dumps”.
And this is the normal behavior of yesterday’s student, who is faced with a task and who must fulfill it. He sees the goal - to implement the desired feature, but does not understand that creating bad code does not come close, but only moves away from it.
So, the first thing to do to combat “dumps” is to enterregular code inspections .
If you have an experienced specialist in your team who understands the “spirit and letter” of good architecture, proper decomposition, transparent code and other rules of good form, then the first inspections should be entrusted to him.
At the same time, he, as a performer, and you, as a leader, need to understand that the purpose of inspections is not to arrange a drag for a careless coder, but to teach him how to write correctly and “infect” with love for a beautiful (no-nonsense!) Code and architecture.
If your team consists of newcomers and there is no such specialist, you will have to educate him yourself.
Improving your code is best to start by dividing large (sometimes just huge) methods into small and neat ones. Usually it’s enough to ask the programmer what each piece does in steps and put these steps in separate methods. Then you need to separate each of the methods in the same way (there is such a word - recursion) until the meaning of each is simple and understandable. I plan to describe this recursive approach in more detail in one of the following articles.
In addition, you can easily set the rule "do not write methods longer than 20 lines long" and check it on inspections. The programmer will be forced to reflect on how to split his “dump” so as not to violate the established “standards”. Of course, this rule, like any others, cannot be regarded as dogma. I can easily imagine a method that will have to use much more than 20 lines to describe it. But, in any case, the programmer will think about it, making the process of writing code more meaningful.
In fact, thinking about it is already a very big and often decisive step on the way to high-quality code.
Further, according to the same scheme, you can teach a programmer to divide one class into several, organizing the latter in the form of layers and modules, and so on.
But that's another story. And now the programmer looks at you in surprise and does not understand why his wonderful method, which took two days to work and which “makes everything work”, you suddenly did not like.
Explain to him!
So, let's imagine that the programmer is faced with the task of writing a new module or adding some functionality to an existing system. What will an experienced specialist do? He pours himself Chinese tea, leans back in his chair, takes a pencil and begins to think. He will draw the structure of the module, think over the entities, interfaces and the interaction between them, go down to the level of specific methods, probably write unit tests on the interfaces. Only then will he begin to fill the existing structure with code (or delegate this task to a dozen Hindu coders).
Now let's see what a typical junior will do in this case. There is a problem - it must be solved. They were so taught at universities. Many of them are still under the influence of the marginal slogan “write code, ## dy!”. So, he pours himself instant coffee, puts on headphones with something tougher and louder and goes into the stream for a couple of hours.
All would be nothing. I have nothing against coffee, headphones, or flow conditions. Moreover, this is usually the most efficient and often the only way to write good code. But we are considering a typical case of a young and inexperienced programmer, so let's look at the results.
What does it look like
Firstly, the functionality is implemented. It works on most cases and looks quite satisfactory. The first thing I want to do is to be glad that the young specialist coped with the task so quickly, praise him and give the next one. But try a peek into the code. You will immediately understand why the fragment was implemented so quickly. And it will be scary.
Here is a code that I usually call a “dump of consciousness stream” . I call the code just like that, because it is written in a single block, without trying to realize it, without trying to return and change something. Below I will list its main characteristics.
Firstly, the code usually consists of one long, very long method. In it, for example, the connection to the database can be initialized sequentially, the desired request is formed, data is received, processed, and (let it be a webdev) HTML is formed for the final presentation. The author writes about what he is thinking at the moment, he is completely in the stream and focused on solving the problem. His consciousness gradually solves the problem and these steps are immediately reflected in the code.
Secondly, this code is usually filled with commented out lines and pieces that are no longer needed, which it is a pity to throw out and do not need to be left.
Thirdly, usually in this code only the main use cases, standard conditions and branches are processed. With a slight deviation from the standard user behavior, the code mercilessly crashes and crashes with unhandled exceptions.
Why is that bad
In part, I wrote about this a little higher, but there are still a fairly large number of factors that need to be said.
The biggest evil from such a code is the absolute impossibility of accompanying it . Indeed, in a few days, not only the “man from the street”, but the author himself will not be able to understand what is happening inside this piece, and for what this branching is responsible. Obviously, programmers, including the author, will not only be reluctant to support such code, but also extremely inefficient.
By the way, this will affect not only the goals of the project, dragging out deadlines and lowering quality , which will undoubtedly upset PMa. Working with such code will seriously undermine motivation.teams from two directions at once, depriving the programmer of his favorite aspects of his work: “I am doing something cool and interesting” and “I am doing an excellent job.”
Another of the sick and unpleasant properties of the “dump of consciousness stream” is that the problems are not immediately visible, since at first glance “everything works”. Very often, testing such a code (of course, by the principle of a black box), the tester encounters bugs that are very difficult to reproduce . Usually they arise due to the intertwined, completely devoid of the structure of the mass of calls and the implicit "leads" associated with it, when one piece of code in a completely amazing way affects the other.
Thus, a testing specialist is added to the “victims” piggy bank to the programmer and project manager already existing there. And in conclusion, in order to assemble a complete project team under this leaky umbrella, we add that the product manager (or the customer in case of custom development) cannot effectively add new features to the product, and the analyst has no idea whether it is possible to make a minimal change , and whether he will hear sky-high dates (or even obscene expressions) from programmers for a simple sentence "to slightly change the operation of the search filter."
The conclusion is simple: a “dump” is an evil that must be fought.
So that this article is not too theoretical, I’ll try to give some tips on how to do this, which I put into practice in my company.
How to deal with it
The first and most important thing to understand when you come across this code is “this is normal . ”
If you have not yet begun to struggle with “dumps” (and your predecessor did not do this), then most likely you have several programmers in your team who use this approach, absolutely sincerely believing that they are doing everything right.
It is likely that newcomers taken to your team directly from the student bench also abuse “dumps”.
And this is the normal behavior of yesterday’s student, who is faced with a task and who must fulfill it. He sees the goal - to implement the desired feature, but does not understand that creating bad code does not come close, but only moves away from it.
So, the first thing to do to combat “dumps” is to enterregular code inspections .
If you have an experienced specialist in your team who understands the “spirit and letter” of good architecture, proper decomposition, transparent code and other rules of good form, then the first inspections should be entrusted to him.
At the same time, he, as a performer, and you, as a leader, need to understand that the purpose of inspections is not to arrange a drag for a careless coder, but to teach him how to write correctly and “infect” with love for a beautiful (no-nonsense!) Code and architecture.
If your team consists of newcomers and there is no such specialist, you will have to educate him yourself.
Improving your code is best to start by dividing large (sometimes just huge) methods into small and neat ones. Usually it’s enough to ask the programmer what each piece does in steps and put these steps in separate methods. Then you need to separate each of the methods in the same way (there is such a word - recursion) until the meaning of each is simple and understandable. I plan to describe this recursive approach in more detail in one of the following articles.
In addition, you can easily set the rule "do not write methods longer than 20 lines long" and check it on inspections. The programmer will be forced to reflect on how to split his “dump” so as not to violate the established “standards”. Of course, this rule, like any others, cannot be regarded as dogma. I can easily imagine a method that will have to use much more than 20 lines to describe it. But, in any case, the programmer will think about it, making the process of writing code more meaningful.
In fact, thinking about it is already a very big and often decisive step on the way to high-quality code.
Further, according to the same scheme, you can teach a programmer to divide one class into several, organizing the latter in the form of layers and modules, and so on.
But that's another story. And now the programmer looks at you in surprise and does not understand why his wonderful method, which took two days to work and which “makes everything work”, you suddenly did not like.
Explain to him!