It is good to be humble, but better to be realistic. Why the parent's self-deprecating sentiment is so popular is beyond me. "I hate my own code" seems to confirm the "to each their own" view, but some ways of doing things really are objectively (but perhaps not measurably) better than others.
When I write code, I write it as well as I can, and I will usually be happy with the result. Then I write more, and as the nature of the problem I'm trying to solve becomes clearer to me, I think of better ways to model the problem and the solution. Later, when I come back to the older code, I will rewrite it to fit the new style.
I am not, at that point, unhappy with the old code. It was written with great care. The fact that I changed my perspective and will proceed to rewrite it with great care does not change that.
I am unhappy with code on a daily basis, but rarely my own. I fully and proudly own up to this, and my intention to rewrite other people's code is not some kind of primitive urge to exercise my power.
It's simply that most code isn't written with care or foresight at all. Those who write the code usually protest the rewrite with "why change it if it works?", but with that kind of thinking you might as well write everything in assembly.
I write code with great care, and I imagine that all who do so would gladly accept suggestions for improvements. That's the kind of humble I think we should be shooting for.
The problem is that many people aren't given the time and circumstance needed for them to write code as well as they can. When a feature needs to be demoed on Friday morning for the large contract to be closed you do what needs to be done to get something that runs and promise yourself you'll fix it when you have time (yet knowing that that time may never come). You know what you did is objectively bad, but you know that to do it objectively better would take longer (probably because it would require you to fix some other rushed part of the code produced under similar circumstances).
I'm always learning. When I come back to some code I've written before, I'm never happy with it because its missing an idiom that I learned in the meantime that would make it simpler. Or, I didn't completely understand the problem, and some of the assumptions I made at the time turned out to be wrong. Or, it's more complicated than it needs to be. Or, its too simple, and I need to add more functionality.
Code is never finished, it's just released. Then modified, and released again. Then abandoned.
Inverse for me. When I'm writing code, I'm never happy with it. I need to get a job done now and can barely spare the time to make it minimally presentable. It's always an embarrassment that I'm happy to abstract away as soon as I'm sure it's correct.
But then, I don't spend a lot of time writing code. I spend most of my time reading other people's code, and most of it is . . . well, let's charitably call it mediocre. But occasionally, I'll come across a piece of code and think, "Hey, that's actually pretty good! Who wrote that?"
Usually? It was me.
Put another way, code that I write under duress to get a job done, I hate at the time. But later I am quite fond of it. Code that I write at a leisurely pace and to my satisfaction, I am proud of at the time. But later it looks naive and foolish.
exactly the same for me. Always wondering if there is a better way to write that line of code. My goal: 100% performance improvement (ie: there is no line of code)
This is why I have found that strong interfaces and assembling teams and developers around those libraries and interfaces, helps them to isolate code away from the developers own code. What this does is get's the team used to looking at other developers code as a block box library in much the same way you would look at a third party jar in java or a gem in Ruby.
When it becomes a library to them, then they stop thinking about it in terms of code and start thinking about it in terms of components that provide functionality. In the enterprise SOA is very aligned to this concept where disparate teams stand up services and the interface become other teams end point in and out of the black box.
Teaching developers to black box code can go along way to curing the I did not write it attitude and forces the developer to document how to use there black box.
Yes. Having pretty clear, hashed out guidelines and a component style to your architecture can do much to ease the itch some might feel to rewrite things.
Clear documentation and a parameter list to the black box you're calling are all you should need to get started on a new piece to the system.
That doesn't look like a problem with replicated and rewritten code; that seems a symptom.
If you don't have somebody "watching the kids" (and with the clear authority and technical abilities to "go all Moe on the other Stooges", when that's needed), kids will have a habit of replicating software. Always have. Kids do tend to get themselves in trouble. That's why you have to watch them. The kids will tend to skimp on documentation and testing and integration, and on refactoring before release, and on consistent APIs and nomenclatures and formatting and development practices.
You can sometimes spot these projects from afar, too; the projects that shipped, and didn't get cancelled. Look for inconsistent or confusing UIs, or poor documentation. For frequent patches, repeated patches, or regressions. Edge cases. A lack of integrated debugging. Problematic upgrades. All can be areas that tend to be short-changed.
Being the "Moe" guy in a project tends to be political; if you're doing it right, you're probably everybody's target. You're balancing what the engineers and the testers and the managers and the customers and the schedule and budget and the egos will permit, and each group is going to be unhappy about something.
He is taking a position as "non-engineer" and stated its goals as clear as water: He considers engineers superfluous(ludicrously overstaffed) but will consider himself indispensable. He tries to justify his position to "making their work-week 20 hours"(and later fire them as they are not necessary, because they only work 20 hours!!)
He is making generalizations, and as such he is right and wrong at the same time.
I could sense the engineers fear to lost their job, and his eagerness to justify it.It is a bloodless war, a power war in the company.He want more power(and money, look!, I got rid of those unnecessary people, I'm worth a lot) and less power and responsibility for the others.
Engineers are people, some are smart, some not. They could look at code and marvel themselves if it is good quality, like a experienced painter when he sees a master piece, or will love to modify it if it is trash, like it uses to be because "there is no time" for making it right.
He is being emotional thinking as the engineers are for protecting their selves.
A chef might not like another chef's take on a dish, but unlike an engineer, you do actually have to prepare a dish each time someone wants to eat it. This alone is enough to make it worth looking at in further detail.
Then replace Chef with Architect, Composer, Writer, Director and etc.: a building is made once, once a piece is published it's done (except for revisions, i.e. updates in the software world) or releasing a film. The point is still correct -- there are a lot careers this post could be interchanged with.
As an aside, this reminds me of something Fred Brooks mentioned in one of his essays in "The Mythical Man Month".
I don't have my copy handy, but he was explaining that the great cathedrals of Europe (some of which took hundreds of years to complete) were only possible because generations of architects were willing to subjugate their own sense of aesthetics in order to maintain the original architect's vision.
If each successive architect decided to start from scratch, the building would never have been finished. And if each decided to build their part consistent with the styles of the time, the building as a whole would be a mess.
His argument (IIRC) was that programmers need to adopt the same mentality: overall consistency in the design takes priority over "doing it your own way", even if your way would be better (if the whole system were redone from scratch).
Software is different because it combines three properties: 1. You have to maintain it over time, 2. It is technically possible to destroy it and start from scratch, and 3. It is difficult to objectively evaluate the cost of doing that in advance.
Buildings need to be maintained, have additions made, walls knocked down, be restructured; Writers often revise their work and release new editions; Directors release remastered films with new technologies, or their own cuts.
Buildings are often knocked down and built in a different manner; books and compositions scrapped; and "technically" the same could be said for films.
And you really think that anyone of the examples I've listed is objectively easy to evaluate the cost of doing them in advance? Buildings and films go over budget all the time, and Writers and Composers are just like software developers: they can be freelance or work on their own, just as easy or just as difficult to evaluate.
Software developers really need to stop thinking they're (we're) special. We're not.
The only code I find myself having to rewrite is something that is both (a) broken and (b) undocumented. If it's documented, with lots of comments letting me know what the original coder was thinking, I have a fighting chance of fixing the problem.
If it's not broken, I'm not fixing it. I've got way too much other code to write to worry whether or not something is elegant or pretty.
The engine was designed to be a simple toolkit; dropping assets into a folder and writing a couple scripts. Entire training applications could be written without touching a line of C/C++.
Sounds like he cloned (at least some) of the system behind Unity3D. I have used that on a couple of projects and if I had a chance to push code to their repository I would have done so too. Worst piece of crap since Win ME.
Anyway the explanations he come up with aren't very useful: he hasn't talked with the developers at all, because if he had he would have known that we change the libraries because they aren't powerful enough. The only way they can become powerful enough? By being so general they might as well use C++.
I think this is related to a variety of factors, some of which seem counter-intuitive at first:
1. writing new code is often easier and faster than reading and understanding somebody else's code well enough to modify it
2. wildly varying differences in talent and knowledge and skill sets between different programmers and teams. A follow-on guy may be much better, or much worse, or just have a totally different skill set at which he excels
3. old code may "work" and be satisfying a lot of old required behavior but some of that behavior is no longer actually required. a rewrite can get rid of the bathwater while keeping the baby.
4. fashion. the new guys want to redo it OO. the later new guys want to put in more Design Patterns. the later new guys want to add Unit Tests. Then rewrite being totally TDD. Then add Aspects. and so on. Meanwhile.... the core behavior actually needed by the business stays, well, about the same.