Not too long ago, my friend Warren tweeted a link to Atkin’s Laws of Spacecraft Design. That in turn got me thinking about Peter’s Laws: The Creed For The Sociopathic Obssessive Compulsive (which I had in poster form for the better part of a decade), and that inspired me to think of truisms I’ve learned about software development over the years. I may not have enough to fill a full 20+ (or even 40+) item list, but maybe I’ll update and add to it over the years. So without further ado, I present to you, Hydrick’s Laws For Software Development.
- If anything can go wrong fix it – to hell with Murphy. Yes, I know that’s a direct quote from Peter’s Laws, but it’s so good that it’s worth making the first item on the list a quote. This is literally why we write unit tests, to make sure these problems are fixed before they’re shipped.
- Error handling checks aren’t paranoia if you don’t control the source of the data. It doesn’t matter if it’s coming from another team within the same company, a third-party API, or even a front-end client that you wrote. If it’s not coming from your database that you validate all writes to, anything can (and will) go wrong, so check everything.
- Don’t assume your users are intelligent or sophisticated – even the most technologically illiterate person you’ve met still uses software at some point in the day. I had to handle a support ticket where someone was confused why he had no data and didn’t know what to do…while looking at a screen telling him that we could detect no data from his site, and that he needed to check his configuration settings to make sure they were correct.
- Don’t assume that just because users are asking for something means that you should give them that feature. Following from #3, rather than assume your customers are stupid, assume they’re like small children. They don’t necessary understand much, but they do want the cool shiny thing. And as your role in this analogy is that of responsible parent, you have to remember that sometimes the best thing for your “children” is to tell them “no.”
- The best applications are the ones that grant the greatest utility for the least amount of maintenance. Obviously, software that’s so useless nobody’s touching it is bad software. But remember that time spent keeping your application up and running is as much a cost as your hosting bills. For the best commentary on the impact heavy maintenance imposes, read this whole 3-part series by Chelsea Troy. Software that people are willing to pay for and you aren’t having to work to keep up and running is basically just a money printer.
- If a service or application requires a significant amount of active maintenance, fix it until it no longer does. This service or application is costing you money by forcing you to pay full-time salaries to maintain the status quo.
- No matter how hastily or hacked together something is, if it shows the slightest bit of use, it’s effectively in production. The good news is, you wrote something so useful people want to ship it. The bad news is, that’s going to have bugs for you to deal with later.
- The smartest people on any team are the ones that figure out how to sneak in “lower-priority” work into their regular workday. Now that you’ve lost the battle to get dedicated time to deal with fundamental problems in the code base, your options for doing this necessary work are: do it as overtime, or wait for the inevitable crisis and do it under a massive amount of pressure. Then there are the people who somehow manage to find a way to do this stuff anyways, effectively justifying it as part of their normal work. You should be learning from these people at every opportunity. They’ll teach you how to keep your sanity and get things done.
- Nobody appreciates technical debt until it’s actively causing problems that cost the business money. As important as it is to work on underlying weaknesses in your code and architecture, it’s next to impossible to get those prioritized until after you really needed that work done. Even then, you generally get just enough time to put out the current fire before getting put back on things that have more visible impacts. It’s sad, frustrating, and an utter indictment of our inability to communicate the importance of the work we know needs to get done.
- The real decision-making power about how software will work lies in the hands of whoever gets it pushed to production. It’s easy to hold off on shipping software for some more review, or 1 more test, or to look at doing things another way. All this does is invite re-thinking and second-guessing software, and keeps it from doing anything useful. Whoever can get through all that to actually deploy it basically ends all those discussions. Shippers hold the power, and what they say goes.
- A depressing number of problems have been caused by not keeping up with certificates. Seriously, set a reminder for when your certificates are about to expire and renew them on time. Or have a cron job do it.
- If a problem seems unsolvable, change the problem. You’d be amazed how easy it is to find an elegant solution to a problem once you step back and focus on exactly what you’re trying to accomplish, without the baggage of what you’re currently doing dragging down your thinking.
- Good QA is worth the time and money. Good QA automation is worth multiples of the first amount. Automation can run on every commit, it enables quick regression testing, and is great for smoke testing deployments. It’s basically all the value of normal, without the manual labor costs.
- When evaluating any new technology, language, or library, the questions that matter are: Does this save me time? Does this save me effort? Does this reduce complexity? If the answers are “No”, then it’s not worth it. Adopting something new should improve your quality of life, and things that improve your quality of life save you time, or save you effort, or add convenience.
- Even if any of those answers are “Yes,” it still doesn’t mean you should re-write your application or service now. Seriously, don’t. Eventually there will be a compelling benefit you can only get by re-writing or refactoring, but until then, let working code run.
- You can be more successful by having a bias towards things that you know you can succeed with rather than trying to optimize your tech stack to be as “bleeding-edge” as possible. “Works well” beats “latest tech” every single time.