
I have a problem - I am a perfectionist. I love the perfect code. After all, this is not only the right approach to writing programs, but also real art. From reading a good listing, I get no less pleasure than reading a good book. Designing the architecture of a large project is no easier than designing the architecture of a large building, and in the case of good work, the result is no less beautiful. Sometimes I am fascinated by how elegantly the design patterns intertwined in the creation of a perfect software system. I admire the attention to detail when absolutely every method is so simple and clear that it claims to be the classic example of a perfect code.
But, alas, all this magnificence is broken about the harsh reality and real projects. If we are talking about a production project, then users do not care how beautiful your code is and how good the architecture is, they care about the project to work well. But I still think that in any case, you need to strive to write correctly, just while fanaticism should not be. After reading various holivars on the topic of correct approaches to writing code, one tendency struck me: everyone is trying to apply these approaches not as a whole to programming, but only to his own development experience, to his projects. Many people do not realize that good practices are not absolute rules that should be strictly observed in 100% of scenarios, they are just tips on how to act in most situations. For every good practice, you can always think of a few dozen examples in which it will not work. But this does not mean at all that good practice is not so good, it was just misplaced.
There is another problem - some programmers are not as good as they think. Often you have to see such a situation: a similar developer saw a single consideration in a large article about a perfect code (without going into context) and began to apply it everywhere, making the code of this developer much worse. And then you have to hear:
“here they are reading articles about such approaches here, and then they start writing this way .
” Or maybe it’s not the articles to blame? If some programmers are crookedly and inappropriately used somewhere heard good practices, this does not mean that the correct approaches to programming do not need to be discussed. The desire to write well is laudable, but you need to soberly assess your abilities. For aircraft pilots, many maneuvers from the category of "aerobatics" are described, but this does not mean at all that every novice pilot must try them all on his first flight. So, after reading the book of the gang of four, the junior programmer should not sculpt all the dozens of patterns he now knows in his next project.
')
But back to the discussion of the perfect code. Approaches to the correct development depend on very many factors: on goals, deadlines, teams, etc. I would like to consider with you several types of projects that differ greatly from each other in their tasks. Let's think together how clean the code should be and how much the architecture should be worked out in each case. In some projects there will be practices that are clearly not appropriate for other projects. When you next time resent the advice in the next article on programming, then think before joining holivar, and which tasks the author had. Maybe this is not bad advice, but simply the author’s projects are different from yours. So let's get started.
Project size
Small projects
For example, there is 1 person who writes a draft for several days. This is some kind of small utility for solving some small individual problem. Most likely, it will not develop much and turn into something big. In such projects, all elements of the system (and maybe all variables) can be kept in mind. In this project, you do not need a cool architecture: if there is some kind of subtask that can be solved with a crutch for two lines, then it is better to do so. Of course, you can spend a couple of days on the development of a complex architecture, which will be very convenient to use when new complex subtasks appear. But there is a nuance: these subtasks are unlikely to appear in a small project, and time will already be spent. In this situation, you should not particularly bother to write super-clean code. There should not be an apple code, just try to write normally.
Medium projects
Suppose we already have 5-6 people and a project for several months. There is not much to talk about, it is necessary to think over the system more or less, to structure the whole code. It would be better to make sure that the crutches are not particularly accumulated. You can spend some time on preliminary analysis and design, but not very much. This is commendable if you have time to draw up an ideal plan for building an ideal system before the deadline, but it would be better if you could write a not very perfect, but working system. At the worst, if everything went wrong, then in a few days it’s not so difficult to work on the whole architecture with joint efforts. (
I had to do this several times, it’s not so scary. ) If this is, say, a custom project, then the customer will pay you not for the wonderful code, but for the working functionality implemented on time. Do not forget about it.
Big projects
And now we have several dozen people, and the project will be written for several years. Here it would be better for us to think very well about the architecture from the very beginning. And if there is a need to insert a crutch, then it may be worthwhile at the early stages to remake the architecture so that the new functionality fits nicely into it. Each hack work done now will turn into terrible suffering in a year or two. Read books about clean code and proper architecture - there are a lot of tips that will be useful to you. Only they need to be applied in place, and not everywhere.
I really like the bike from
Martin Fowler 's
book : Fowler was engaged in advising one firm to develop a fairly large project. The project was written badly, and Martin insisted on a little refactoring. After a couple of days of work, I managed to remove half of the code without any damage to the functionality of the system. Programmers were very happy, but the bosses were not enough - because this work did not lead to the emergence of a new functionality. The old code worked fine, the activity of “cleaning” it did not seem economically justified. Therefore, the management did not heed further advisory advice, insisting that the new functionality be available as soon as possible without any additional work on the code. Six months later, the project was closed, because the code has become too complex to support.
Project support
Projects without support
Activities familiar to various freelancers and outsourcers. After the delivery of the project you will never have to remember about all this horror that lurks under the hood. In the depths of your soul, you hope that the project will simply be used, and no one will ever open the source code. And this is a valid approach, because we are not required to have a wonderful code, but a working application. At the beginning of the project, you can still afford to design the architecture, pee the clean code, but when there are two days left until the deadline, and the functionality is only half implemented, then there is no place for high matters. It is permissible to drive in any crutches, violate conceivable and inconceivable approaches to good code. And in this case, it is normal. I do not say that it is good, I do not agitate everyone to always do so. But it normal. Here we are not talking about programming, as about art, here we are talking about a project that needs to be delivered on time and does not need to be supported. If you start writing everything in an ideal way, then you just run the risk of not meeting the deadlines - you will let the customer down, you will not get money, you will spend your time, and the code will still be useless to no one. Always remember your immediate goals.
Projects with support
And here I would try to write normally. So that the architecture was normal, and the code would be clean. This is such a wonderful feeling when the customer asks to add some non-trivial functionality, and you cope with the task in an hour - the new code is easy to add, because it fits nicely on the existing architecture. It is very easy to work with a ready-made code base, the code is quite understandable, it’s easy to navigate. And there is another feeling when a customer asks to make some trifle (and it’s incredibly obvious to the customer that this is really a trifle, it should be very, very simple), and you look at the current cacophony of classes, estimate how many days you need to spend for this trifle, but for some reason I don’t want to touch the keyboard. Yes, and look at this code is just disgusting.
Scale of the project
Internal projects
You are writing a project for yourself or your team, not going to show it to anyone. In this case, you are allowed a lot of liberties. No one, of course, makes you deviate from the ideals of software development approaches, but if you really want it, then you can - there is nothing wrong with that. There is no need to develop competent documentation, comments can be written in the native language (if all the persons involved in the development understand it), and some non-trivial architectural solutions (not at all obvious from the code) can be explained in words to teammates. I am not saying that it is imperative to do so. But if, say, you are in a hurry somewhere, then some good practices can be neglected.
Public projects
Here we have a completely different situation. It would be better for you to properly document your project so that it does not arise every day for a hundred questions from your favorite users. And it would be better to write documentation in English (as, however, and comments). And it would be better to write the code more cleanly, so that it would be easy for a person from the outside to understand it. If you have an API, then it would be good to
think it
through , and not just stick some interface from which, with a strong desire, you can somehow pull out all the necessary data. Remember that the project belongs not only to you, but to third-party programmers - respect those who will work with your code. Write the program so that then you do not want to catch in the dark alley and do bad things with you.
Projects with specifics
High load projects
Highload is a separate conversation. In practice, you have to sacrifice a lot in terms of high performance, including good architecture and readable code. Sometimes you want to cry with bloody tears, looking at what your cozy project turned into after optimization. But what to do? But the time of the program has been reduced by half. Sometimes you don’t have to choose too much.
Projects using third-party libraries
When I start talking about third-party libraries, some of my colleagues start looking at me with an understanding look. And I see them in their faces - they have experienced the same suffering as me. In the real world of a large project, you rarely will write absolutely all of the functionality yourself. Usually come across very common tasks that someone has already solved. In this situation, it would be much more sensible to take a ready-made solution than to reinvent the wheel yourself. That's the way it is, but sometimes it turns out that the authors of this ready-made solution are not very good programmers. Their project copes with its main task, but it was written ... Well, not quite professional. And integrate it into your project ... Well, somewhat complicated. This circumstance once again makes you write awful crutches, disfiguring your nice architecture. But this is another production necessity, because it is often unprofitable to implement this functionality yourself. (
I will say in secret, several times I did not stand up and wrote my library instead of third-party. But this is the exception rather than the rule. )
Novice Team Project
You can often hear the statement that any average developer should know this, that and that. It is assumed that the developer knows the language well (let's say, if we are talking about OOP-language, then you need to at least know what polymorphism and inheritance are), can easily perceive complex syntactic constructions, understand the basic mechanisms of the platform, know the elementary design patterns (after seeing the class with the name Visitor, he will immediately understand a certain fragment of the system), easily reads comments in English and can do a lot more. But before becoming an average developer, everyone was new at one time. And today in the world of programming there are many people who are just beginning to comprehend this craft. It is quite normal that they do not know and do not know how many things. The situation is quite normal when several novice programmers gather and write a small project. In the development process, they will learn a lot. Of course, they will do many things not quite right. But from them and do not expect this. It would be nice if the senior colleagues suggested different points: how to rewrite the code better, what books to read. But it is precisely to make demands on them on a par with seniors should not be. In the draft of newbies, many deviations from that “as it should be” are permissible, because they are just learning. Tips and tricks are good, but the requirement to write an ideal architecture with perfectly clean code the first time is not very good.
Non-production projects
Demonstration Projects
Sometimes I have to write demo projects to show my colleagues some cool things. It can be a language, engine, library or something else that these people have never encountered before. As a rule, the demo project has to be written in great detail and simply, copiously supplying the code with comments. In some individual cases, there may be several dozen lines of comments per line of code - and this is normal. You do not write a perfect project, you simply use the code as an illustration. And the code itself can be very crooked and work for a long time, but all this does not matter - after all, we have other goals, which are to demonstrate to the public some technology.
Academic projects
In this project, we don’t really show anything to anyone, but we ourselves deal with some interesting thing. Let's say we study some algorithm. It is quite normal to write alongside 10 versions of the algorithm. Perhaps the version will be in different languages. It is quite normal to spit on naming conventions (which it would be good to observe when developing a real project) and to call the same things with the same names - those that are indicated in the book. What difference does it make in what language to write? We are dealing with the algorithm here, now we should not worry about such things. If you are going to show someone the result, then you can already work on the code, but it will be a completely different story. And while you are at the stage of learning, your main goal is to study, not to write the perfect code. Of course, these things can be combined, you can try to write the most ideal implementation of the algorithm, but this is not at all necessary. The main thing is not to replace the main academic goal with the goal of a perfect code.
Local projects
Well, many will say that you should immediately get used to writing everywhere correctly. But the local code has its own specifics - it does not need to be shown to anyone, there is no need to report to anyone, you can be guided by some of your own considerations when developing. During the workflow a lot of intermediate bad code may occur. You can play with the platform, to conduct several experiments. You can conduct development as we are comfortable. For example, you can make some data dump, regardless of the overall architecture, simply by saving to a local file from the most inappropriate place. In the course of work, you can write any number of comments in any language - if it is more convenient for us to work.
But remember that the situation changes completely when the creative process ends and you will need to show your results to others (say, send local developments to the central repository). Before this, the code must be “combed”. All our experiments, crutches and unnecessary comments should be removed, the remaining code should be made as understandable and readable as possible. Respect those who will deal with your writings.
Prototype projects
The task of such projects is to quickly distribute certain functionality in order to make it clearer how it will look. This is a very reasonable approach. Let's say we have 5 implementation options: we try to briefly distribute the general concept of each option. After that you can see all the approaches on live examples and choose the one on the basis of which the main project will be built. It is very important to correctly understand the tasks of prototyping. You do not need to read such code, you do not need to try to write it perfectly. I am always saddened by people who swear at the prototype with statements like
“this variable can be called a little clearer” or
“but it would be nice to move this button in the interface 1 pixel to the left” . But what difference does it make to you, how the variable is named there, this is a prototype, leave it alone. Such discussions can be carried out at the finished project, but at the level of the prototype it makes no sense.
Recreational projects
I remember once, my friends and I decided to give one good man a birthday present. We made a Java-project, which in the OOP-form represented his life, his friends and various interesting things with which he interacts. And the program really worked, from the console it was possible to execute various cheerful commands. As for the source code, absolutely all the naming (classes, methods, variables, etc.) were written in Russian (good Java allows you to do this). Javadoc was also written in Russian and did not carry any useful information. The logic was implemented in the simplest way. Instead of fast complex algorithms, we used the simplest ones. The architecture was not very beautiful, because we did not even try to think it through.
A gift was a success, even though we did not use any good practice in writing perfect code. But the thing is that the project’s goals were completely different.
Summary
I would like to once again fix your attention on some basic thoughts. If you want to become a good programmer, then you must constantly evolve, learn to write better, grow above yourself. You should always try to write as clean and good as possible. But you need to understand that in a large project your code will never be perfect. You should not put up with govnokod, write so that you are not ashamed. But you should not forget about the goals of your current project, because the desire for perfect code in most cases is not the goal, but only the way to achieve it. It is true that there is no need to intentionally bydlokodit, try to always write correctly, but you shouldn’t show any special fanaticism either. Remember your goals, remember the situation in which you are. Writing a perfect code is not so easy. Weighed against the improvement of the code and the effect that these improvements will give. If you have read some article about a good code, then there is no need to pull out separate tips that you rush to take everywhere without any hesitation. Pay attention to the context in which these tips are provided. Think about exactly what the situation is. Think about the cases in which it is appropriate to use well-known good practices, and in which cases not so much. And in general, think more, it is useful in programming. And everything will be fine with you.