Home Development of Websites Programming: A Case Study

Programming: A Case Study

by admin

Programming: A Case Study
There is probably not a single new or fresh thought in this article, in fact, I’m sure you’ve read something like this many times before. Nor does this article claim to be the truth. Its contents are the fruit of my own experience, trial and error, and at the same time the compilation of knowledge I’ve managed to get from my colleagues, read on Habra and other places. Probably for each individual what is said in this text will be very different from reality, but I’m sure many can recognize in the description of himself. The first stage is probably not very typical for programmers who were not engaged in olympiad programming when they were students or apprentices, but the next stages almost do not depend on this factor.

Stage one. Birth

"I’m a programmer. I’m an olympian. I know what "o"-small is. I know what "O"-large is. I understand the difference between "en-squared" and "en-factorial" and why they both hide shamefully at the sight of "en-logarithm-en". Now I’ll come to the project and rewrite this retarded mess of code so that it runs many times faster! Look, I know the Knuth-Morris-Pratt algorithm! And here you can save one comparison of lines for equality! And if this recursion is turned into a loop, then at the cost of saving method calls and allocating memory in the stack… What, is the program slowing down? Let me look at the code… Here! Look, here you can write one loop instead of two nested loops and use binary search instead of internal one!"
Meet the first stage. It, unlike the following ones, is especially characteristic of olimpiadniks. The patient thinks about how to write fast code. He is obsessed with fast code. Unfortunately, having fast code doesn’t always make the software product as a whole fast.
The patient rewrote a piece of code that is executed once at the start of the web server in the optimal way and it had no effect on overall performance. The patient rewrote a piece of code which was then changed 10 times due to changing project requirements and its micro-optimization caused a bunch of hard-to-find bugs. His algorithm runs in linear time, while the old one ran in quadratic time, but the old one made one query to the database, while the new one does it in each iteration. The patient doesn’t realize that there are many users working on the web project simultaneously, and using static data is fraught with… We can go on for a long time.
The patient’s main problem is that he thinks in terms of a couple of classes or methods and is not really aware of what’s going on around that part of the project. His thinking is limited to the code and the algorithm of how it works, i.e, how program works, not by the fact that, that it is supposed to do. However, this stage rarely lasts long enough for the patient to harm himself or others. Pretty quickly the realization comes that something of what he is doing he is doing wrong, and he begins to learn.

Stage Two. Idealism and self-confidence

"I’m a developer. Yes, that’s right, I’m a software developer, not a programmer. My job is to develop a product that works consistently and consists of the right code. The code I write has to work correctly first and then quickly. The code must be structured and commented out – perhaps it will be supported by other developers. OOP is my main tool, I know how to analyze the subject area and distinguish class hierarchies in it. Everything that can be described by templates or generics is described by templates or generics. I use declarative programming whenever possible because it makes the code as readable and comprehensible as possible. I use codogeneration as it saves me the time of writing code. I only use new technologies. I spend a lot of time arguing with my colleagues about which pattern or technology is best for the task at hand and whether this or that approach is the right one…"
And this is the second one. The patient has matured and learned a lot during the previous stage. Knuth’s dictum that premature optimization is the root of all problems has been memorized and burned into the patient’s body. What he cares about more than anything else is not performance, but beauty code.
Giant trees of class hierarchies cover the project with a dense forest, special attributes, generics, and interfaces hang from their rampant crowns. In the thick of this forest monolithic rocks rise object factories, callback functions, observers, iterators, visitors, controllers, and other members of the gang of four fans roam. Somewhere deep in the forest, code is generated, which in turn generates code, which generates code, which generates XSLT template, which generates the user interface. All the code is lavishly covered with comments about how to use it properly and what it does. The patient’s delight is in projects that he can’t figure out in less than a few days because of non-trivial object-oriented structure.
Changes in requirements are often accompanied by large-scale refactoring, introducing another abstraction layer, isolating new entities, and applying new techniques and approaches, which I just read about on Habra. After reading an article about defensive programming he starts shoving asserts into all the methods. After getting acquainted with caching data in memory he caches all the data in the project. After getting acquainted with TDD he writes a bunch of tests for elementary logic before writing the logic itself. The fruit of his labors is monumental and delighted colleagues at the same stage. He sincerely believes that the language in which he writes is perfect and that the technology is state-of-the-art. Often the patient will start a blog in which he writes about how correct write code or use a particular framework, describing bugs found in his code and witty, as he thinks, ways to fix them and prevent them. He subscribes to the blogs of his favorite technology evangelists and listens to their words as the ultimate truth.
When confronted with the fact that his brainchild is slow, he takes a profiler and tries to make sense of the call tree a thousand stories high. Sometimes he succeeds and the problem is solved… yes, by introducing one more abstract layer with additional caching. Or vice versa, some of the logic is transferred to the database server in the form of stored procedures.
When a project deadline approaches, the patient suddenly realizes that too much is not ready, and time is spent constantly refactoring and arguing about which pattern to choose. He sleeps at work to meet the deadline, and sometimes he succeeds. However, once the project is finished, you still have to maintain it, add new functionality for the next version and meet the demands of new users, suddenly It turns out that it’s almost impossible to fit the new functionality into the monolith of the project without destroying it to the ground. As there is no time for total destruction, as the product is already in production and this bug should have been fixed last Friday, the code starts to be updated with crutches, fixes, quick and dirty fixes with comments "todo: fix this later". And the more monumental the design, the more monumental the props and crutches for it.
The patient’s problem is that he has lost the content behind the form. He writes code the way an artist paints a picture: with enthusiasm, with admiration, he is in love with this code and often forgets that the main aim of his work is not to write beautiful code, but a product which will work, will work quickly and will be easy to maintain. He often forgets that a software product is a product which must find its buyer to whom ( no, just think about it! ) doesn’t care about the concentration of patterns per line in the program code. But this user is willing to pay money to have a new feature added to the product, which nobody guessed when writing the first version, moreover adding this feature should not damage any of the existing project’s functions and this process should take minimum time. And yes, it’s really important to the user that these buttons have rounded corners.

Stage Three. Enlightenment

"I think I’m wrong. No, definitely, I’m wrong."
Yes, the third stage is the patient’s realization that he is in the second stage of the disease and an understanding of his own shortcomings and mistakes. Awareness of the disease leads to healing.
Hierarchies of classes in the project rarely exceed two or three levels of inheritance, methods contain no more than a couple dozen lines, and most often less than ten. The code contains almost no comments, with the exception of external interfaces, which can be handled by third-party developers who do not have access to the code. Surprisingly, the lack of comments does not make the code unreadable – correct variable and method names, clear code-convention and small code volume works wonders. If an action can be described simply and without complex design patterns, it will be described that way. If there is a possibility that a more complex solution will make life easier in the future, it will be implemented exactly enough to provide that simplification.
Declarative programming is used where it doesn’t hurt performance. Code is generated, but only where it saves developers time, and the result of generation is as simple and debugged as possible, even if you have to generate ten times as much code to do so. Unit-tests cover only a part of the code, but it is exactly the part which can suffer in case of an error when introducing new functionality or fixing a bug. Before adding data caching from the database, the patient will definitely think about how necessary it is, and whether the scalability of the solution will be damaged, just as in the case of transferring the logic to the stored procedure code on the database server. He realizes that buying another server might end up being much cheaper than rewriting and testing part of the project. However, in those places where optimization can give a serious performance gain it … is not done for the time being, but the code is written in such a way that it can be easily accelerated if necessary. If that’s what’s needed, of course.
The puppyish enthusiasm for technology and languages is replaced by a more relaxed attitude–everything has its time and place. The patient understands that each tool is good for a certain range of tasks, so he does not take part in the "dynamic languages vs. static", "Java vs. C++" and so on. He is happy to try new languages and technologies for his own projects, but dares to use them in his working code only after careful weighing of pros and cons and trying out innovations on a prototype or a separate branch of the project. He is critical to everything new, trying to find both pluses and minuses in it, and carefully listen to all sides of the dispute, if there is one. He knows several languages and technologies well enough to solve any problem set before him, but not enough to master them to the extent he needs. The sayings of evangelists and gurus are not taken by him as the ultimate truth-he is trying to understand not so much the that they have said, but why And why does it have makes sense If the patient understands that in a certain case his own bicycle may be more effective than existing technology, he writes his own bicycle, but only when he proves to himself its necessity. If he enjoys the aesthetics and clever solutions, and if he is in agreement with his employer, he won’t hesitate to publish the code under an open-source license, or at least describe the solution in general terms on his blog. And yes, if these idiots really want to see rounded corners in the buttons, the patient will definitely make them. Is the patient, though?

Instead of an afterword

I’ve never met the patient myself – it’s more of a composite spherical image living deep in a cosmic vacuum, written off from my friends, colleagues, my own experiences, and just stories without authorship or origin that pop up from time to time on various resources on the Web.
Thank you.

You may also like