Criminal Reengineering
- Transfer
Programmers are often blamed for doing their job sloppy. In nature, there are countless programs that crash, freeze, or suddenly write on the Preved Bear screen a million times. What is the result? Something like this:
Such an experience is the reason that encourages people to say big words about Microsoft and curse anonymous programmers who unexpectedly (though inevitably) did not live up to their expectations. We all know this; it is burnt in our souls with the endless hours of technical support that we provided to family and friends. From time to time, we see how programmers who do their work quickly and carelessly make other people suffer. And so we try, we damn try not to be like that. We try to be good programmers who check every return value and handle every exception.
If we limited ourselves to error handling and rigorous testing, everything would be fine. But in truth, we usually go much further, and alas - I have to admit it - in the wrong direction.
A huge share of the working software is terribly redesigned . I'm not even talking about interfaces overflowing with controls and settings. These are truly terrible sins, but they are only the visible part of the iceberg. Much worse reengineering happens below the surface, in the code itself.
Have you ever seen someone uses a design pattern " Strategy " where he could have used a simple design switch 5 lines?
There are a million ways to turn a simple construct like this: into a disgusting, wrong mutant monster, such as this one , which I did not build into the article because it is too long . The most insidious cause of reengineering is over-generalization. We re-generalize everything that even a drop lends itself to generalization. Writing a code to work with a list of students? Well, we could work with teachers, and indeed with the general public. Someday
. It is better to add the base class Man and his subclass Student . Or you can create the class Man , inherit the Learning Man class from him and the Student from him . Yes, that's much better, isn't it?
That’s how it is, only now we have to support as many as three classes, each with its own virtual methods and interfaces, possibly divided into three different files, while a dictionary (map, map) in one line would be quite enough .
Perhaps we do this because it relaxes - drumming three classes full of code without having to stop and think. It gives a feeling of productivity. This solution looks solid, bulletproof, professional. We look back, warmed by a spark of self-satisfaction - I am a good programmer , no dirty hacks in my code !
Everything would be fine, but that does not make us good programmers. Such reengineering does not make anyone's life better; it only makes our code longer, harder to understand and change, and increases the likelihood of errors in the code. We just made the world a little worse. It lies somewhere between throwing bottles in the middle of the street and car theft.
The extra effort caused by our reengineering also incurs hefty costs:
Yes, by reengineering the Student class, you indirectly ruined Miss Alauren's day .
We must stop advocating every ridiculous trick of reengineering and call them by their proper names. This is not a “reserve for the future,” because we cannot foresee the future . This code is not reliable - it is hard to read . Applying a generalized solution to a particular case is not good programming, it is a criminal reengineering , because you like it or not, but someone will have to pay for it somewhere.
I suspect all the best programmers have long understood this, but they did not shout about it loudly enough for everyone else to hear. Paul Graham is absolutely right when he suggests brevity should be appreciated:
Actually, he was talking about language design; indeed, in the article “ Brevity is Strength ” he clearly shows that it is possible to write too short a program. This is because at the moment, Paul Graham is more of a language designer than an existing programmer. Otherwise, he would say:
When I feel tempted to overly generalize or redesign a piece of code, it is often triggered by fear. Fear that someone will find a really good reason why I should not have chosen a simple solution. Fear that I will have to rewrite this code. Fear of being on the wrong side in a dispute over the merits of the Visitor template . But fear, of course, will never lead us to the most elegant decisions.
Next time, when you feel the urge to write a good, general solution for a simple problem, stop and ask yourself what is stopping you from writing a simple, concrete and short solution:
If one of these options is your case, then relax. Do not worry. You worry, you call me, I make you happy (line from Bobby McFerrin ’s song “ Don’t worry, be happy ”: “You worry, you call me, I make you happy.”).
And take and write a simple, specific, short solution and add a short comment to it like this: Replace with a Visitor template if this code starts to grow .
This is the perfect solution. The next time you get into this code, this comment will remind you of what you wanted to do. It will show other programmers that you were considering a more “correct” (complex) solution, and at that moment you had a good reason not to start making it for now. It’s hard to argue with such a comment, because you did not discuss what is better: the Strategy template or switch, you just discussed whether to use the Strategy template for a simple task of 3-4 cases. In any case, this is definitely not the kind of discussion that can show you the bad side.
After a few months, you can come back and see how many of your comments ultimately turn into more complex code. I bet quite a bit. That's how much time and effort you saved. This frees up hands to continue solving the original problem, and makes the world a little better.
Related links:
1. Stop Over-Engineering! (April 2002); a software-centric discussion from Software Development magazine.
2.Reengineering ; Wikipedia article
3. Briefness is power ( original )
Damn computer and Excel ruined my whole life! Hate my life.
Miss Alauren (like any other at one point or another in her life)
Such an experience is the reason that encourages people to say big words about Microsoft and curse anonymous programmers who unexpectedly (though inevitably) did not live up to their expectations. We all know this; it is burnt in our souls with the endless hours of technical support that we provided to family and friends. From time to time, we see how programmers who do their work quickly and carelessly make other people suffer. And so we try, we damn try not to be like that. We try to be good programmers who check every return value and handle every exception.
If we limited ourselves to error handling and rigorous testing, everything would be fine. But in truth, we usually go much further, and alas - I have to admit it - in the wrong direction.
A huge share of the working software is terribly redesigned . I'm not even talking about interfaces overflowing with controls and settings. These are truly terrible sins, but they are only the visible part of the iceberg. Much worse reengineering happens below the surface, in the code itself.
You do it wrong
Have you ever seen someone uses a design pattern " Strategy " where he could have used a simple design switch 5 lines?
There are a million ways to turn a simple construct like this: into a disgusting, wrong mutant monster, such as this one , which I did not build into the article because it is too long . The most insidious cause of reengineering is over-generalization. We re-generalize everything that even a drop lends itself to generalization. Writing a code to work with a list of students? Well, we could work with teachers, and indeed with the general public. Someday
switch(operation)
{
case OP_ADD: return a + b;
case OP_SUBTRACT: return a - b;
case OP_MULTIPLY: return a * b;
default: throw new UnknownOperationException(operation, a, b);
}
. It is better to add the base class Man and his subclass Student . Or you can create the class Man , inherit the Learning Man class from him and the Student from him . Yes, that's much better, isn't it?
That’s how it is, only now we have to support as many as three classes, each with its own virtual methods and interfaces, possibly divided into three different files, while a dictionary (map, map) in one line would be quite enough .
Perhaps we do this because it relaxes - drumming three classes full of code without having to stop and think. It gives a feeling of productivity. This solution looks solid, bulletproof, professional. We look back, warmed by a spark of self-satisfaction - I am a good programmer , no dirty hacks in my code !
Everything would be fine, but that does not make us good programmers. Such reengineering does not make anyone's life better; it only makes our code longer, harder to understand and change, and increases the likelihood of errors in the code. We just made the world a little worse. It lies somewhere between throwing bottles in the middle of the street and car theft.
The extra effort caused by our reengineering also incurs hefty costs:
- Less time is left for honing the user interface;
- Less time is left to think about the significant consequences of the features we are working on;
- Less time is left to search for errors, and (given that the amount of code has increased) more time will be required to correct them.
Yes, by reengineering the Student class, you indirectly ruined Miss Alauren's day .
We must stop advocating every ridiculous trick of reengineering and call them by their proper names. This is not a “reserve for the future,” because we cannot foresee the future . This code is not reliable - it is hard to read . Applying a generalized solution to a particular case is not good programming, it is a criminal reengineering , because you like it or not, but someone will have to pay for it somewhere.
Don't worry be happy
I suspect all the best programmers have long understood this, but they did not shout about it loudly enough for everyone else to hear. Paul Graham is absolutely right when he suggests brevity should be appreciated:
We take the length of the program as an approximate estimate of the amount of work required to write it. not the length in characters, but the length in various syntax elements - in fact, the height of the parse tree. It is not entirely true that a short program requires less time to write, but it is close to the truth. Take a look at the program and ask yourself, is there a way to write it shorter?
- Paul Graham, The Hundred Year Language
Actually, he was talking about language design; indeed, in the article “ Brevity is Strength ” he clearly shows that it is possible to write too short a program. This is because at the moment, Paul Graham is more of a language designer than an existing programmer. Otherwise, he would say:
If you are going to write a hundred lines of code to solve a problem that could be solved with ten lines, stop and ask yourself: what the hell?
- Mark, Criminal Reengineering
When I feel tempted to overly generalize or redesign a piece of code, it is often triggered by fear. Fear that someone will find a really good reason why I should not have chosen a simple solution. Fear that I will have to rewrite this code. Fear of being on the wrong side in a dispute over the merits of the Visitor template . But fear, of course, will never lead us to the most elegant decisions.
Next time, when you feel the urge to write a good, general solution for a simple problem, stop and ask yourself what is stopping you from writing a simple, concrete and short solution:
- I'm worried about having to rewrite it?
- Am I worried that someone will criticize him or that I will look stupid?
- I'm worried this is not professional enough ?
If one of these options is your case, then relax. Do not worry. You worry, you call me, I make you happy (line from Bobby McFerrin ’s song “ Don’t worry, be happy ”: “You worry, you call me, I make you happy.”).
And take and write a simple, specific, short solution and add a short comment to it like this: Replace with a Visitor template if this code starts to grow .
This is the perfect solution. The next time you get into this code, this comment will remind you of what you wanted to do. It will show other programmers that you were considering a more “correct” (complex) solution, and at that moment you had a good reason not to start making it for now. It’s hard to argue with such a comment, because you did not discuss what is better: the Strategy template or switch, you just discussed whether to use the Strategy template for a simple task of 3-4 cases. In any case, this is definitely not the kind of discussion that can show you the bad side.
After a few months, you can come back and see how many of your comments ultimately turn into more complex code. I bet quite a bit. That's how much time and effort you saved. This frees up hands to continue solving the original problem, and makes the world a little better.
Related links:
1. Stop Over-Engineering! (April 2002); a software-centric discussion from Software Development magazine.
2.Reengineering ; Wikipedia article
3. Briefness is power ( original )