After having seen a lot of software engineers, inspected their code, fixed their bugs and otherwise worked closely with them... I've determined that there a several types of software engineers. Now I'm sure a lot of you are going to bristle somewhat at the fact that I'm categorizing people. Face, we're all categorized all the time. If you've ever filled out a census form... you've been categorized. So agree or disagree, that's fine. However I also think most of you will probably relate to this very well and have observed very similar phenomena. None of these categories are absolute. Most software engineers posess some blend or mixture of all of them.
The first type of engineer is what I call the "Code-Writer." This engineer is probably the most dangerous type to have on your team. At first, you're excited by having this engineer. I mean, this person cranks out mountains of code very quickly and it actually works. So what's the catch? Version one of your product ships, gets great reviews, there's a few rough edges, but, hey, it's version one. So you now start working on version two. This is where the "Code-Writers" begin to show their true colors. You now ask them to add a new feature to their code. Whoops! The first thing they do is come back and say "I gotta rewrite the whole subsystem!" Not just refactor it, or tweak the design a little bit, bit wholesale drop the bits on the floor sweep them into the trash and start fresh.
The problem is this. This person is just a Code-Writer. They can't look at a chunk of code and fully understand it in such a way that they can effectively maintain and enhance it. Even for code they wrote themselves! This type of engineer is especially prone to do this for code they didn't write themselves. More times than not, it is far worse to rewrite code rather than refactor and redesign. This means that more time is spent, unit-test have to be redone, and QA is not confident and has to do a full regression cycle on the entire product.
This next type of engineer I call the "Code-Reader." This engineer is probably the most useless type of engineer for a software production team. As the name implies, this engineer is really good at reading and understanding existing code, whether they've written it or not. Mostly not, because as the name also implies they don't ever really write code. Oh sure, they may actually type some code into the editor, compile it and even have it working... only on their machine! So either way (never really write code or simply never check it in), this type of engineer is an albatross around any software team's neck. For the ones that actually write code but never actually check it in, this is typically a confidence issue. They are afraid to check in because they may break the build, or someone will not like their code, or there is some other fear that keeps them from actually submitting code. The former, the one never even writes code, is probably a lost cause... the latter is probably salvagable if you have a psychologist on staff and can figure out why their parents hated them... Bottom line, you eventually stop assigning critial tasks to this person which tends to feed more into their insecurrities. It can quickly spiral.
This final type of engineer, the "Code-Designer," is a wiley bugger. This person interviews very well, and is usually hired on in a more senior capacity. He impresses the managers and even the other engineers on the team. The thing is, this person is a great thinker... and that's it. Ask them to actually write the code behind their killer application design and architecture... well you may as well ask them to compose a Concerto in Dminor... Oh, they actually write code.. check it in... and it even passes the unit-tests. But when you look at the code, it is hideous! Poor and inconsistent formatting of the code is the rule. It looks like 20 different engineer's wrote the code with no eye for a consistent or team agreed-upon coding style. CS101 algorithms are about all you get in terms of implemenation details. And finally, the actual code only peripherally matches the design. So, on paper, the design is great and gives great Powerpoint... but when the rubber meets the road.. it's flat.
So there's the categories. The Code-Writer, Code-Reader and Code-Designer. The good news is that most engineers are a blend of all three. I'd say that the most valuable and generally useful engineers are the "Code-Reader-Writers". They are good solid mid- to high-level engineers. They produce the bulk of the product's code. Most Code-Reader-Writers also will have a good amount of Designer in them as well which means that they can solve problems in very clever and robust ways. They also have some level of leadership skills and are good mentors. You need your team to have more of these engineers than the next valuable blend.
The Code-Reader-Writer-Designer is the next most useful blend. As the name implies, this is a senior-level engineer that also provides a high-degree of technical leadership while maintaining a good down-to-earth understanding of the day-to-day bits and bytes. They can usually jump in anywhere in the product and be helpful and productive. It is good to have a few of these on the team with the number proportional to the team's size and age.
Some teams may actually have a Code-Designer, but most folks call them the analysts or the architect. Many times they never actually work on the code but instead prefer to live their life in Powerpoint, UML, Visio, and email. This actually works for a lot of very large software teams that have huge numbers of Code-Reader-Writers and/or Code-Writers.
So there you have it... my personal, totally biased, non-scientific, probably irrational categorization of software engineers.