I was musing about the different developers I meet, and I began categorizing and labeling people. Never a nice thing to do out-loud, but something that can help you understand why some people are so much more successful than others as software developers.
So, this is where I get theoretical, metaphorical, and a little pretentious.
I think that in college they teach you syntax. If an application was a plane, syntax would be what gives it lift -- it gets your code off the ground. If you don't know syntax, the program won't compile and writing working code is hopeless. Every professional developer knows the syntax of the languages they work with. It is fundamental.
Another skill you are taught in college are solutions or patterns to typical problems. Problems can be broken down to smaller problems and each smaller portion solved with simple bits of code. Everybody makes a big deal out of design patterns and algorithms, but they are simply the fundamental tools of solving problems. The more tools you have, the quicker and more readily you solve problems. If we stick with the airplane metaphor, this is the skill that gives your development cycle thrust. It propels you forward.
A skill you aren't likely taught in college, but learn either on your own or by having coworkers nag the crap out of you, are destructive habits and patterns that lead to bugs. This area of development tends to be filled with subjectivity, misinformation, and good intentions. Poor developers will cling as tightly as they can to the building block patters they know, but not understand why that -- when they put these perfect patterns together -- they don't get working software. In our airplane metaphor, the ability to avoid common obstacles gives our development cycle lateral movement, allowing us to bank left or right and find a workable course toward our destination.
The fourth and most common mental skill to be a "good programmer", in my estimation, is the ability to see ahead of your current position in the development cycle. You've plotted your course by laying out a great design, avoided habits and anti-patterns that might making your application fail to work properly, and it is syntactically amazing. Then everything goes wrong because you didn't see the ramifications of one little change. You put in a line of code in one file to adapt to a new requirement and -- wham! You smash into a wall of bugs. First, one other completely unrelated feature stops working, then you put a bandaid on that only to notice more issues. A good programmer will know before they make a change to the code (a change necessary due to requirements or other bug fixes) what the ramifications are and whether the change will cause future issues. In our airplane metaphor, it's about the pilot thinking ahead, seeing problems before they are really problems and avoiding them. For our development cycle, that see-and-avoid mentality when making a change saves time, money, and a lot of late nights at the office.
That's all it takes to be a good developer. Sounds easy.
There are people who are more than "good developers" though.
Not everybody has a mind for five, six, and seven dimensions. So this may not be the best way of describing this whole concept. I've given you four dimensions so far, and I hope it wasn't too much of a stretch. Don't feel bad if it is. It doesn't make you dumb. It's just a concept that isn't natural to everybody. Unfortunately, I'm doomed to continue this description. That fourth dimension of time -- seeing ahead of the development cycle assumes that if you make the changes you plan to make that no outside factors beyond your current knowledge will influence your development cycle. So, we must continue on!
A fifth dimension is the lateral possibilities. The ability to see alternate patterns that achieve the same goals, but have different tradeoffs. Sure, you know a few design patters and can string a few algorithms together to make something happen. Good for you. But solutions aren't black and white. Every solution has tradeoffs. Seeing which perform better, save memory, and cost less time or money to develop give us a whole line of possibilities. What problems might arise from each choice, and what are you going to do about it? This dimension is simply about understanding that no one solution is perfectly right or wrong and that every one has tradeoffs.
A sixth dimension is the forward possibilities. The ability to prepare for features that nobody has thought of yet. To provide the extensibility and forethought in your design and choices of lateral possibilities that you account for the likelihood and needs around requirements that may someday exist. These are the non-technology possibilities -- the business and people factors that impact the development cycle by creating new, profitable, and interesting directions for the software you build.
The seventh dimension is the vertical possibilities. The ability to look at the two dimensional array of possibilities in the fifth and sixth dimension, and see the impact of evolving technologies and the ecosystem in which your software exists and must adapt and survive in. When a project starts, you might think you know what hardware your application will run on, which database you'll use, which browsers you'll support... whatever. It is easy to take this for granted. Knowing that some of your choices will be more restrictive and unforgiving to changes in the technological ecosystem your application lives in could be costly.
Do the best developers think in twelve dimensions? I don't know. I thought of these seven while eating a burrito at Chipotle for lunch today without any real effort into digging for deeper arrays of meaning. Seeing an eighth dimension is actually a fair amount of mental gymnastics and too much heavy lifting while enjoying lunch.
I look at the young people coming out of college and the people on their second or third career, and I want them to know that there is more to development than syntax. That they can be a good developer, but that we should strive to be more.
I tried to break down and simplify that which I don't really analyze when I myself am making choices. I simply study the problem and evaluate the myriad of choices before me and select what I think is the most pragmatic and likely choice. After all -- being able to see all of the possibilities, if there is such a person, isn't as important as being able to find the most probable and pragmatic path through to the successful release of your software.
You don't have to build a solution that can be extended in every possible way -- sometimes it is enough to know that if that possibility exists, you haven't made it impossible. Acknowledging and knowing what you are doing is part of it. We mitigate risks, we do our best, and in the end, we make the best choices we are able to. I don't always make the right choices, but with every passing project I become better at it. You learn from experience what outcomes are more probable and it helps you make those best decisions.
I won't say "correct" decisions -- because saying that one solution is right or wrong is something that only a person who doesn't see possibilities can dare say.