Software engineering is all about finding and applying the best ways to solve technical problems with software (which is why it's so much fun). If you watched Paolo Perrotta's Baruco 2012 video in the previous lesson, you saw how attempts to replace software engineering as just another commoditized production process failed. In particular, how the comparison between Engineers and builders breaks down.
That's because software engineers aren't just builders and software isn't a commodity. The compiler (which turns source code into something the computer can execute) is what actually does all the building. The engineer, on the other hand, must figure out what the compiler is actually supposed to build. That requires creative problem solving.
Engineers are thus much more like architects or even designers -- they live firmly in the design phase of the problem solving process and are frequently required to solve loosely defined or unusual problems. Their techniques for doing so therefore are less concerned with building quickly than they are with finding and designing the right solution amidst trying out new things.
That's not to say that software engineers aren't constantly coming up with tools (like languages and frameworks and boilerplate code) to make the design of their software "blueprints" more efficient... but there will always be a need for someone to figure out what to build in the first place.
Because of the inherent creativity required to solve software problems, the source code of multiple engineers building the "same" thing will probably look very different. Despite this, if they stick to established principles, patterns, designs and methods to do so, then they will all likely arrive at similarly effective solutions and will have accomplished the task at hand.
These principles, patterns, designs and methods for producing good software form the core of software engineering. Many were inherited from other engineering disciplines while others are hard won epiphanies from years in the trenches of building software. In this lesson, we'll take a look at some of these high level guiding principles and best practices.
Our goal for this lesson isn't for you to remember all these principles and acronyms but for you to absorb what it means to be an engineer and how engineering "works". The specifics will flow from that higher level understanding later on.
There's no major mystery to engineering -- you just apply a systematic process for creatively solving problems. What that looks like is this:
What most people don't understand is that most of the significant effort goes into the first two parts of the process. If you fail either of those, it hardly matters whether you've carried out your plan perfectly or accurately. So if you want to think like an engineer, solve your problems fully BEFORE diving into the implementation of your solution.
This is easier said than done -- engineers often love creating things to the point where they would rather dive into building something interesting than make sure they're solving the right problem. Wait, that seems sort of familiar...
In the Design mini-course we said that if you're designing a product because you think it's fun to design and not because it's what users want, it's going to fail. A similar principle applies to engineers writing code -- if you find yourself coding mostly because building is fun and you didn't fully explore the problem or plan your approach ahead of time, then you will waste a lot of time.
If you pay attention over the remainder of this mini-course, you'll see all kinds of parallels between the ideas of good User-Centered Design and good software engineering.
Engineers really like acronyms and rules of thumb because they represent clarity and simplicity. In fact, just about everything you need to know about software engineering can be summed up with the following principles, rules, and acronyms. Most apply to other forms of engineering as well. In the list below, they start high level and then get more code-specific towards the end.
The most important ones to absorb are the high level ones -- you'll be able to come back later and ponder some of the more software-specific ones once you've had some time behind the wheel of real code.
KISS (Keep It Simple, Stupid!) -- you saw this one back in the section on UX, remember? KISS might just be the engineer's motto. We've acknowledged our tendencies to build overly complex systems at times (there are anonymous meetings for this kind of thing) and it's forced us to admit that simplicity makes your solution so much better.
That's not to say simplicity is easy! It's often the result of hair pulling and teeth gnashing as complex solutions are refactored to break apart their core components. KISS applies in countless other ways as well -- among beginners, for instance, there's a real tendency to over-think logical problems and come up with strange and novel solutions when the "dumb" simple way is simply better.
Learn, especially from your mistakes -- Engineering is always changing and software engineering in particular might be one of the most rapidly changing fields on the planet. You need to always be learning, both from other people in the industry and from acknowledging your own mistakes and crappy code. That's the recipe for a long and stimulating career in the field.
Remember the reason the software exists -- there are countless small decisions that you'll be faced with during your work as a developer and, if you don't know the bigger picture, you might waste time going down the wrong path. This is pretty much the foundational principle behind why we've created these mini-courses for you!
Remember that YOU won't be using the software -- it's very tempting for engineers to design solutions for themselves. Remember what we talked about in the Design mini-course and it will serve you well here! Think about the user not yourself. Don't assume your user will have the same level of technical competency or familiarity with the system as you do.
Adapted from Rules of Thumb in Software Engineering by Markus Sprunck
...so do you get the major themes yet? Think first. Break problems into pieces. Keep things simple. If you've figured that out (and we probably don't need to hammer them in any harder at this point, do we?), then you're officially on the same page as the rest of the engineering community. Everything else is just implementation detail.
To finish up, check out Principles of Software Engineering (part 1) by Nathan Marz. It could instead be called "Engineering for Uncertainty". He goes into some specific terminology which might not make a lot of sense but his perspective should give you a good feel for how a software engineer views the world. He also has some great points about the difference between how systems are designed and how your users will actually use them (and what that means for the software engineer).