The Illusion of Effective Design: Design
This post is a continuation of: The Illusion of Effective Development: Management
We all studied programming, almost all of us went through the stage of asking questions at forums, in conferences, and sometimes in teams. Conventionally, all respondents can be divided into 2 groups: those who know the answer to your question and those who know how to correctly . They are the prophets of the standard, they are the apostles of a just cause, they and only they can shamelessly tighten your project, hiding behind the perfect architecture and licked code. They are the world behind the scenes of the IT world, which, without knowing it, determines what will be in trend in the next few years.
If you’re tired of reading, I’ll just say that the essence of this post is that you think with your own head. Or they thought with their own heads and kept thoughts unspoken, if you plan to work long and productively in the current place. Everyone else welcome under cat.
The problem is as old as the world - using an idea without understanding its meaning. In our case, it all starts when a person acquires advanced design techniques who does not have enough experience to understand why they are needed, or does not have enough knowledge to formulate a connection between the typical tasks of the industry and the approaches described in the book. The result is one - the proposed ideas are accepted on faith. And due to a lack of understanding of the scope, there is an application of these ideas where they are not applicable.
The IT world is good in that those who do not study do not linger in it for a long time. And a gradual understanding of why OOP really is needed, patterns, etc. still comes to such programmers. Those who did not understand anything, it is very easy to determine by peremptory judgments in favor of any approach and willingness to recognize people of the second grade all those who do not adhere to this approach. And if this is a timlid at the head of the Hindu regiment, then this behavior can still be somehow explained, but otherwise, I think that such timlids should learn a lot from the movie hero of the immortal creation of Svetlana Baskova, who urges everyone to be people.
Do not stop asking yourself each time why the approach you use should be applied in a particular case. Be aware of what problems this approach solves. Make sure these problems exist in your project. If, as a result of this simple procedure, you come to the final justifications of the form “this is good practice”, or even “my faith is strong,” then perhaps this is an indirect sign that the chosen approach is not suitable in this case.
The mind of every decent young web-programmer excites the question: how many connections does highload start with? The mind of every decent architect is occupied by two questions: what is the minimum level of abstraction to do in the designed system so that further expansion does not turn into hell, and also how high a level of abstraction can be done into it, so that development and support do not turn into hell. There are many such questions, but it all comes down to which patterns and architecture to use for a project of a certain scale. The problem is complicated by the fact that often the ideas about the development prospects or the project attendance are very vague, while the time and budget do not immediately and thoroughly solve the problem. At the same time, the architect is still required to create something that meets all conflicting requirements.
Different people solve this problem in different ways. Someone decides not to bother with the structure, believing that if the project takes off, then there is money to rewrite from scratch, and if it does not take off, then there is no need to spend effort. Someone, designing a system that can do everything, begins to aim the gun at the sparrow, but by the time of pointing, despite the filigree accuracy of the calculation, it turns out that the sparrow has departed, and the time and budget are doubled. Someone just gets drunk from hopelessness, thus moving away from solving the problem. And someone may be lucky enough to guess the requirements for the system that time will supply, and then an excellent product with wonderful architecture is obtained. And someone designs according to current requirements or with a small margin in the calculation to lose a little time, but at least leave the possibility of further expansion. Usually,
In my opinion, today there are still no clear methods for determining whether, from which moment, the application of such and such an architectural approach is justified. Those. there are collections of approaches, application cases are described, but the border where such a case begins is not described elsewhere. Usually, understanding when to apply comes with experience, but conveying such an experience with words is not an easy task. The specifics of the industry are such that almost every new architecture differs from the existing ones, just so much so that the advice on the new architecture to a person who has no business with the old one is useless.
Just remember that no matter how elegant the pattern appears in the book, no matter how attractive the idea is to cover all the code with tests, no matter how cool it is to have an architecture “in reserve”, all this may ultimately prove to be a burden for your project, and not an aid . Decide for yourself what you need and what you are willing to sacrifice for - far from always neglecting things without which, as it is believed, a normal code is unthinkable, will cast you to the ninth circle of hell.
Today we have many great projects like github.com, sourceforge.net, etc., not to mention code repositories for specific languages. And it was their presence that played a significant role in terms of instilling the belief that bicycles are bad and that there is always a ready-made solution. Of course, if you decide to write your gui-toolkit for windows or the template engine for php, then I would drop all unfinished business, get up, fasten my pants and go away from your field, while expressing the majority opinion.
But as soon as we take on something a little more atypical than the above things, we will face the full-scale problem of the quality of those libraries that seem so accessible. By quality, I mean 3 things:
If you look at the quality of libraries soberly, you can still allow the option when you have to write an analogue yourself. Just because it will be easier. It will be faster and more efficient. So it will be wrong. And your bike can really be special - in the sense that even with an imaginary abundance of solutions, none of them will suit you fully. Although you can get indulgence for this sacrilege by posting your version on github. So that others get burnt on it or write their own. And the application deployment time is directly proportional to the number of libraries that need to be deployed with it.
Separately, there is the problem of choosing between a new project or developing an existing solution. This choice weighs heavily on web-programmers - the lion's share of projects on the web are pretty typical, for which there are engines of cms, web-shops, social networks, etc. At first glance it always seems that it is logical to finish an existing solution to the requirements of the TOR than to write your own bike from scratch. This seems especially logical after several projects are carried out on the same engine in a row, and quickly and elegantly. However, you can get burned, having rested in the limitations of architecture or in a fancy layout, or even in the speed with which everything will work after the work is completed. For myself, I deduced a rule of thumb - if the project takes according to my estimates more than a month, it’s better to write from scratch or on a general purpose framework. Well, the best - I’m better, and you have to derive your rules depending on what you are working with.
Just remember that there are times when parsing xml with regular expressions is preferable to using binding to libxml, and writing a seemingly simple online store will be easier on Yii than on the basis of PrestaShop. Everything, of course, has already been invented before us, but not all of this is embodied in the code in such a way that it can be conveniently used.
One of the easiest ways to earn credibility in the IT world is to follow trends. The sooner you join the trend, the better. You will think and check how effective the trend is in reality - you will not be in time in the forefront, and you will not see the honorary title of senior-bleeding-edge-developer. I'm not saying at all that the new is bad, I even believe that applying new technologies can somehow help you beat your competitors (but I still think that a good sales manager or excellent usability will give you an order of magnitude more chances win championship than competent architecture). I just want to note that before choosing a newfangled framework for your project, it's nice to be sure that:
Again, be aware of why you chose the new Y technology, if you have X technology that is already well tested, has a community, and is generally used everywhere.
I thought for a long time what to write here, but somehow it turned out that it was too voluminous or too specific, because of which many would have thought that I was an ideological opponent of some technologies and approaches. Therefore, I will limit myself to five points:
So understand them as you want. And remember the difference between Olympiad and industrial programming.
Experience is the son of difficult mistakes. And what to do when there is no experience, but you want to avoid mistakes? Here, books on pickup are used. And in case of programming all sorts of best practices. After reading this and at least memorizing the set of rules for good code, you can write code so that no one dares reproach that something is written wrong. It's great. At the same time, the fact that you have to pay for everything is missed. Until you yourself reach the need for techniques (other than simple ones), they cannot be used effectively and will, for the most part, take your time. If yesterday’s student, who has successfully created dozens of php sites, reads “Perfect Code” and tries to use all of this in practice, then most likely his work will succeed, although the quality of the code will improve in some places. And so it will be as long as until he walks the rake himself in some large project, until abstract constructions from books find a match from real practice. Only then will the understanding of what, when and why to use come.
But do not go back from the roots - many of the same students, having gained experience over several years, begin to believe that copy-paste and procedural programming are among those that cannot be called. The reason is the same - the fear of mistakes. Unfortunately, now it is more acceptable for the community to use the right solutions, rather than finding a tool for the task.
Just don't be afraid to make mistakes. If you are sure that it will not cost you a loss of reputation and work.
To admit, this whole article was inspired by the fact that I had to work in teams with different team leads, each of which had its own ideas about how to write code correctly. They were all right in the details, but the trouble is that each of these parts differed greatly. Moreover, I risk assuming that if all of them are brought together at the same table in a pub, and after the conversation is turned into a comparison of imperative and functional programming, or about the differences between Dependency Injection and the good old Factory, then it will not do without the intervention of the guard.
All team leaders are also people, they all have their own beliefs and knowledge gained through the implementation of some of their projects. Sometimes such beliefs are true, sometimes not. Sometimes the latter may seem to you due to the fact that you have not yet encountered tasks that would lead you to an understanding of why you need to do just that. In any case, take everything that the team leader says as his requirements, and not as really good things. If his advice passes the test of practice - great, but if not, then to convince a person of this kind of error is usually useless.
There are no universal rules for good design. There are rules that can be beneficial in a situation. Even if there are a lot of such situations, this does not mean that you will not encounter another when the rules that once helped were useless. And do not forget to ask yourself the question why you chose this particular solution to the problem, and not another.
We all studied programming, almost all of us went through the stage of asking questions at forums, in conferences, and sometimes in teams. Conventionally, all respondents can be divided into 2 groups: those who know the answer to your question and those who know how to correctly . They are the prophets of the standard, they are the apostles of a just cause, they and only they can shamelessly tighten your project, hiding behind the perfect architecture and licked code. They are the world behind the scenes of the IT world, which, without knowing it, determines what will be in trend in the next few years.
If you’re tired of reading, I’ll just say that the essence of this post is that you think with your own head. Or they thought with their own heads and kept thoughts unspoken, if you plan to work long and productively in the current place. Everyone else welcome under cat.
Perfect Code Church
The problem is as old as the world - using an idea without understanding its meaning. In our case, it all starts when a person acquires advanced design techniques who does not have enough experience to understand why they are needed, or does not have enough knowledge to formulate a connection between the typical tasks of the industry and the approaches described in the book. The result is one - the proposed ideas are accepted on faith. And due to a lack of understanding of the scope, there is an application of these ideas where they are not applicable.
The IT world is good in that those who do not study do not linger in it for a long time. And a gradual understanding of why OOP really is needed, patterns, etc. still comes to such programmers. Those who did not understand anything, it is very easy to determine by peremptory judgments in favor of any approach and willingness to recognize people of the second grade all those who do not adhere to this approach. And if this is a timlid at the head of the Hindu regiment, then this behavior can still be somehow explained, but otherwise, I think that such timlids should learn a lot from the movie hero of the immortal creation of Svetlana Baskova, who urges everyone to be people.
Do not stop asking yourself each time why the approach you use should be applied in a particular case. Be aware of what problems this approach solves. Make sure these problems exist in your project. If, as a result of this simple procedure, you come to the final justifications of the form “this is good practice”, or even “my faith is strong,” then perhaps this is an indirect sign that the chosen approach is not suitable in this case.
From paper airplane to shuttle
The mind of every decent young web-programmer excites the question: how many connections does highload start with? The mind of every decent architect is occupied by two questions: what is the minimum level of abstraction to do in the designed system so that further expansion does not turn into hell, and also how high a level of abstraction can be done into it, so that development and support do not turn into hell. There are many such questions, but it all comes down to which patterns and architecture to use for a project of a certain scale. The problem is complicated by the fact that often the ideas about the development prospects or the project attendance are very vague, while the time and budget do not immediately and thoroughly solve the problem. At the same time, the architect is still required to create something that meets all conflicting requirements.
Different people solve this problem in different ways. Someone decides not to bother with the structure, believing that if the project takes off, then there is money to rewrite from scratch, and if it does not take off, then there is no need to spend effort. Someone, designing a system that can do everything, begins to aim the gun at the sparrow, but by the time of pointing, despite the filigree accuracy of the calculation, it turns out that the sparrow has departed, and the time and budget are doubled. Someone just gets drunk from hopelessness, thus moving away from solving the problem. And someone may be lucky enough to guess the requirements for the system that time will supply, and then an excellent product with wonderful architecture is obtained. And someone designs according to current requirements or with a small margin in the calculation to lose a little time, but at least leave the possibility of further expansion. Usually,
In my opinion, today there are still no clear methods for determining whether, from which moment, the application of such and such an architectural approach is justified. Those. there are collections of approaches, application cases are described, but the border where such a case begins is not described elsewhere. Usually, understanding when to apply comes with experience, but conveying such an experience with words is not an easy task. The specifics of the industry are such that almost every new architecture differs from the existing ones, just so much so that the advice on the new architecture to a person who has no business with the old one is useless.
Just remember that no matter how elegant the pattern appears in the book, no matter how attractive the idea is to cover all the code with tests, no matter how cool it is to have an architecture “in reserve”, all this may ultimately prove to be a burden for your project, and not an aid . Decide for yourself what you need and what you are willing to sacrifice for - far from always neglecting things without which, as it is believed, a normal code is unthinkable, will cast you to the ninth circle of hell.
Wall bike
Today we have many great projects like github.com, sourceforge.net, etc., not to mention code repositories for specific languages. And it was their presence that played a significant role in terms of instilling the belief that bicycles are bad and that there is always a ready-made solution. Of course, if you decide to write your gui-toolkit for windows or the template engine for php, then I would drop all unfinished business, get up, fasten my pants and go away from your field, while expressing the majority opinion.
But as soon as we take on something a little more atypical than the above things, we will face the full-scale problem of the quality of those libraries that seem so accessible. By quality, I mean 3 things:
- functionality - you need to personally feel the moment when it is discovered that the selected library does not have 10% of the functional on which 90% of your project will be held. Developers are people like you, and usually these very necessary 10% include the dirtiest work that no one wants to do.
- documentation - poor documentation is just the scourge of all young projects, and without it, welcome to the code
- code quality - determines the possibility of expanding and or even studying the API in case of poor and missing documentation
If you look at the quality of libraries soberly, you can still allow the option when you have to write an analogue yourself. Just because it will be easier. It will be faster and more efficient. So it will be wrong. And your bike can really be special - in the sense that even with an imaginary abundance of solutions, none of them will suit you fully. Although you can get indulgence for this sacrilege by posting your version on github. So that others get burnt on it or write their own. And the application deployment time is directly proportional to the number of libraries that need to be deployed with it.
Separately, there is the problem of choosing between a new project or developing an existing solution. This choice weighs heavily on web-programmers - the lion's share of projects on the web are pretty typical, for which there are engines of cms, web-shops, social networks, etc. At first glance it always seems that it is logical to finish an existing solution to the requirements of the TOR than to write your own bike from scratch. This seems especially logical after several projects are carried out on the same engine in a row, and quickly and elegantly. However, you can get burned, having rested in the limitations of architecture or in a fancy layout, or even in the speed with which everything will work after the work is completed. For myself, I deduced a rule of thumb - if the project takes according to my estimates more than a month, it’s better to write from scratch or on a general purpose framework. Well, the best - I’m better, and you have to derive your rules depending on what you are working with.
Just remember that there are times when parsing xml with regular expressions is preferable to using binding to libxml, and writing a seemingly simple online store will be easier on Yii than on the basis of PrestaShop. Everything, of course, has already been invented before us, but not all of this is embodied in the code in such a way that it can be conveniently used.
At the forefront of technology
One of the easiest ways to earn credibility in the IT world is to follow trends. The sooner you join the trend, the better. You will think and check how effective the trend is in reality - you will not be in time in the forefront, and you will not see the honorary title of senior-bleeding-edge-developer. I'm not saying at all that the new is bad, I even believe that applying new technologies can somehow help you beat your competitors (but I still think that a good sales manager or excellent usability will give you an order of magnitude more chances win championship than competent architecture). I just want to note that before choosing a newfangled framework for your project, it's nice to be sure that:
- in this framework there is at least a part of the functionality really necessary for your project
- it is true that this functionality can be applied - well, i.e. to take and use, I do not dance with a tambourine, so that it somehow works
- you are so confident in yourself and your subordinates that you know that if you come across an error due to which all development can get up, you can eliminate it by debugging and digging into the insides of the framework
- you have time to implement the previous paragraph
Again, be aware of why you chose the new Y technology, if you have X technology that is already well tested, has a community, and is generally used everywhere.
Theory and practice
I thought for a long time what to write here, but somehow it turned out that it was too voluminous or too specific, because of which many would have thought that I was an ideological opponent of some technologies and approaches. Therefore, I will limit myself to five points:
- Do not take for the truth the calculations of theorists (this article, for example) or someone else's experience if you are not sure that it was obtained on the basis of creating a solution very close to yours.
- No matter how convincing the documentation examples are, remember that they are often synthetic
- In general, any concept is invented to solve a problem or a class of similar problems, there is no guarantee that your task harmoniously fits this class
- Complicated at first glance, the concepts applied to your task can result in a couple of lines that are understandable to most rural computer science teachers
- Be very careful about the concepts "not for everyone" or "ahead of their time", which for years remain the destiny of a small group of people - they may turn out to be excessively difficult to use, but often just practically useless
So understand them as you want. And remember the difference between Olympiad and industrial programming.
Just not to be mistaken
Experience is the son of difficult mistakes. And what to do when there is no experience, but you want to avoid mistakes? Here, books on pickup are used. And in case of programming all sorts of best practices. After reading this and at least memorizing the set of rules for good code, you can write code so that no one dares reproach that something is written wrong. It's great. At the same time, the fact that you have to pay for everything is missed. Until you yourself reach the need for techniques (other than simple ones), they cannot be used effectively and will, for the most part, take your time. If yesterday’s student, who has successfully created dozens of php sites, reads “Perfect Code” and tries to use all of this in practice, then most likely his work will succeed, although the quality of the code will improve in some places. And so it will be as long as until he walks the rake himself in some large project, until abstract constructions from books find a match from real practice. Only then will the understanding of what, when and why to use come.
But do not go back from the roots - many of the same students, having gained experience over several years, begin to believe that copy-paste and procedural programming are among those that cannot be called. The reason is the same - the fear of mistakes. Unfortunately, now it is more acceptable for the community to use the right solutions, rather than finding a tool for the task.
Just don't be afraid to make mistakes. If you are sure that it will not cost you a loss of reputation and work.
Timlid - our king, father and god
To admit, this whole article was inspired by the fact that I had to work in teams with different team leads, each of which had its own ideas about how to write code correctly. They were all right in the details, but the trouble is that each of these parts differed greatly. Moreover, I risk assuming that if all of them are brought together at the same table in a pub, and after the conversation is turned into a comparison of imperative and functional programming, or about the differences between Dependency Injection and the good old Factory, then it will not do without the intervention of the guard.
All team leaders are also people, they all have their own beliefs and knowledge gained through the implementation of some of their projects. Sometimes such beliefs are true, sometimes not. Sometimes the latter may seem to you due to the fact that you have not yet encountered tasks that would lead you to an understanding of why you need to do just that. In any case, take everything that the team leader says as his requirements, and not as really good things. If his advice passes the test of practice - great, but if not, then to convince a person of this kind of error is usually useless.
Conclusion
There are no universal rules for good design. There are rules that can be beneficial in a situation. Even if there are a lot of such situations, this does not mean that you will not encounter another when the rules that once helped were useless. And do not forget to ask yourself the question why you chose this particular solution to the problem, and not another.