I’m not the first person to address this subject but I recently felt compelled to add my $0.02 worth on this subject.
I have heard several times in my career people say something like the following, “You can teach any high school kid how to program, …”, followed by some other colorful statement. This is usually in reference to someone’s frustration with a software engineer simply not implementing a “quick and dirty”, naive, solution and instead insisting on taking the time and actually engineering a solution.
I find this statement both insulting and at the same time it is 100% accurate. You can teach any kid how to program. I taught myself Basic on a Commodore 64 when I was 12 years old. But I should not have to explain to anyone that there is a vast difference between “some kid who can program” and a software engineer. It also doesn’t help that popular culture is full of stories about some kid writing an app and making millions. While it’s true that there have been some successful applications that have been written by young programmers, it is almost always the work of software engineers to turn those successful programs into sustainable, maintainable, extendable, scalable, robust, fault tolerant, intuitive, and basically well engineered applications.
I’m sure you can think of many products in which you can see the results of a naive solution that has not been well engineered. It typically neither performs well, nor is it capable of scaling well, or handling large data sets, or it’s not robust or fault tolerant, or it’s just simply difficult to use. These are costly lessons for any company if they are unfortunate enough to create such a product. They have the initial cost of developing the product, then they have the cost of rewriting or significantly refactoring that product. Not to mention the cost of lost credibility and damaged reputation with customers.
I believe we should challenge our engineering team members to try to not simply implement the first solution that comes to mind. This is especially true with our junior team members. With aggressive time constraints we can let ourselves get into bad habits. I have fallen victim to this in the past and recently caught myself doing it again. To me a software engineer doesn’t simply approach a problem or task with one solution. A software engineer has many tools in his or her “solution toolbox” with which to approach a problem. It is up to the engineer to evaluate several possible solutions to a problem, consider, many factors such as scalability, performance, complexity, maintainability, testability, as well as how easy the solution is to understand by other team members.
That last consideration is a very important one in my mind. While programming is typically an individual effort, software engineering is most definitely a team effort and communication among team members in software engineering is absolutely paramount. I know that under aggressive deadlines it’s easy to fall into “execution mode”, and stay in our cubes heads down coding. We need to do our best when presented with aggressive deadlines to push back as much as we can, and allow ourselves the time to do our jobs well as engineers, and not just as programmers. That is actually part of being a good engineer. It is our duty to do the best job that we can with the given resources, and if the resources are not sufficient, it is our duty to communicate that to leadership.
Great products almost never come from just programming the first naive solution that comes to mind. Well engineered products come from a lot of hard work: design, testing, prototyping, analysis, and talking through and iterating on designs with other engineers. Just like eloquent and clean code are almost never the first lines of code you write, instead it comes through refactoring, testing, and actually using it. Good designs and well engineered products come from the same sort of efforts.