Do you think you have what it takes to ship software? I’ll let you in on a secret: it’s not easy and takes a lot of effort—but it’s all skills that you can learn.
Here’s my checklist for getting software projects done, in a way that they actually ship and actually work well:
To ship software, first learn how to design things for humans
It’s a skill like any other to learn: design things for humans. I don’t mean visual design (though that is part of it), I mean looking at a problem and figuring out how to create human-computer interactions that make people successful at solving the problems without having a hard time, instead of just defaulting to putting up yet another CRUD form with a few standard UI components that map to some database fields.
A good way to get started is to use other people’s software and take notes about tasks you’re trying to complete and what you actually need to do to complete them. In my email client, how many clicks do I have to make to reply to someone? How many labels do I need to read? How often do I need to switch between the mouse and keyboard? Does it help me in any way with common tasks (like “find all attachments from a specific person”)? (You’ll be surprised how hard it is to use software!).
To put it in other words—give people what they need, not what they want. No one will actively tell you: “I want fewer labels!” or write you an email that they “would like to only switch between the mouse and keyboard 1 time when using the ‘log time’ button”.
It’s your job to figure out the many little things they need in order to successfully use your software and kick ass at what they want to achieve. You can’t outsource this by hiring a designer on oDesk or just asking your customers what they want.
Stick to a few languages. Master them.
If there’s a better solution in another language or environment only use it if gives you some really amazing advantage. It’s often not worth the extra effort to become proficient enough with yet another tool.
Don’t underestimate what it means for a production environments: things have to be provisioned, deployed, security-patched and monitored.
Don’t follow the hype
Use what works for you. If you’re productive in PHP, by all means, use PHP. Of course, sometimes technologies come along that actually measurably increase productivity or have other huge advantages, but it can’t be overstated how few and far between those are—perhaps one or two happen in a decade.
Don’t step into the trap of believing that because there’s many variations of a specific technology, that the underlying idea is a good one. It might actually be a sign of people trying in vain to find a technological solution for the wrong high-level approach.
For example, client-side MVC, for almost any type of web application functionality, will add programming overhead (because there’s more layers and those require interfaces between them), lessen productivity (more code to write and the layers make debugging harder) and likely not actually improve the experience for users.
User interface design is hard work and using client-side MVC will not magically do it for you. You’re a lot likelier to ship by sticking to “old-fashioned” technology.
Stick to a style
Just like languages, frameworks and libraries, the way you use a language seems to change like seasons. One month it’s put it all in closures and the next month your hear that closures are so passé. Reduce cognitive stress while coding and debugging so you have more time thinking about the actual problem you want to solve.
Implement that minimum viable solution
It can’t be said often enough: when writing code, don’t write anything that the code doesn’t absolutely need in order to work. Don’t anticipate how you may extend the code in the future. It never turns out that way anyway. Concentrate on code that works, and write tests instead of wasting time on too much abstraction.
Don’t forget: code is not written in stone. It’s easy to refactor or rewrite later when you do need to change or extend it and when you actually know the requirements.
For example, I don’t use CSS or HTML preprocessors like HAML or Sass (if they work for you, awesome, please use it and be productive!)—my style of coding and refining apps involves a lot of tinkering and I have an easier time if I can mess with these things on a low level (for example, just copying and pasting styles I messed with in browser development tools into a CSS file directly).
Coding > Configuration
An easy trap to step into is relying overly much on other people’s code. If they use it, and all these other people use it, it must be good. Right? Incidentally, that’s why most people run Windows. This is what’s called satisficing.
Your brain is optimized to find the easy way out. It will tell you to just throw a component or library at it, and most programmers will agree. Why reinvent the wheel? Suffer from NIH much?
Choosing an off-the-shelf component is almost always not the optimal way to solve a problem. You’ll suffer through having that pre-fabricated solution only solve your problem the first 80%. And then suddenly there’s no configuration option for that little thing that should be so easy to do. And then you have to start refacoring and fixing bugs in that library. And then you fork it. And you probably need to figure out how to run and adopt the tests. And then you find out there are no tests. And then…
You’re a programmer, not a configurator.
Try tracking your time doing various tasks while programming, including thinking about how to implement a specific feature, designing human-computer interfaces and interaction, writing outlines and todo-lists for the feature’s implementation, picking tools and libraries to help you, making prototypes, writing the actual code, coming up with tests and iterating over functionality and bugs.
You’d be surprised how little time you actually spend coding versus how much time can go into picking libraries and configuring them.
You might save a lot of time by just sitting down and writing code from scratch instead. I find that writing code often helps me understand the problem domain better, by forcing me to think about edge cases—often these would probably never have occurred to me if I’d just pick some off-the-shelf library to do the job.
You’d be surprised how little time you actually spend coding versus how much time can go into picking libraries. You might save a lot of time by just sitting down and writing code from scratch instead.
Never stop learning
Perhaps the best way to stay sharp is to occasionally do side projects. These are a great way to enjoy trying out new things without introducing technological clutter into your “real” projects.
Maybe write an open-source micro-library or two and use it to share things that you have learned to work well with others.
Experiment and tinker, so you don’t lose the joy of programming—creating things out of nothing.
tl;dr To successfully ship software, you need to understand humans better. Design a simple solution. Enable people to be awesome at solving whatever problem it is your software promises to “make easy”. Oh, and don’t over-engineer.