avatarNicklas Millard

Summary

The article provides advice on delivering better software by following the principle of "make it work, make it better, make it faster."

Abstract

The article emphasizes the importance of focusing on what matters at the right time when crafting software. It suggests following a simple one-liner advice from the author's mentor: "make it work, make it better, make it faster." The article explains that making it work is about fulfilling requirements, making it better is about improving code, design, and approaches, and making it faster is about optimizing hot paths. It also highlights that there's no shame in writing trash code as a first step, as long as it's cleaned up before pushing the code. The article also discusses the importance of making code better by refactoring, re-architecting, applying design patterns, and assessing if the code is SOLID. It also emphasizes the importance of not rushing off code tuning every line and optimizing only if there's a bottleneck.

Opinions

  • The author believes that making things work by violating principles of good design in a quick, hacky way is completely fine.
  • The author thinks that dreaming up premature, elaborate up-front designs is entirely useless.
  • The author emphasizes that users couldn't care less about how much better the code is compared to the mess made earlier.
  • The author believes that making software better is not just about refactoring, but also about re-architecting, applying design patterns, assessing if the code is SOLID, fixing code smells, and taking care of edge cases.
  • The author thinks that optimizing without a target performance is not going to end well.
  • The author believes that premature optimization is just as bad as applying a design pattern prematurely.
  • The author suggests writing the simplest code possible to begin with and then refactoring, redesigning, and optimizing only if there's a bottleneck.

The Best Advice for Delivering Better Software (From My Mentor)

Crafting great software is about focusing your attention on what matters at the right time

Photo by the author.

Rubbish software is produced when we try to do everything at once.

Principles, guidelines, best practices, and rules of thumb — they all make your life easier. Without them, ten-minute tasks can turn into ten-hour tasks.

One of the absolute best pieces of advice I received from my mentor very early on in my career was this simple one-liner:

“Make it work, make it better, make it faster.”

It’s a slight alteration of Kent Beck’s famous quote, and its simplicity is enabling and puzzling.

“Make it work” is quite easy to wrap your head around. You have a set of requirements, and you’re coding to fulfill them — kid stuff.

“Make it better” is where the meat is. “Better” is the juicy part that you’ll spend the majority of your day achieving. Better code, better design, better approaches. But what does “better” mean? We’ll get around to that later.

Well, let’s be honest: You often never get around to the “make it faster” aspect of your code — at least not for every part of the software. You want to make your hot paths fast and efficient, but you’re likely in good shape, leaving paths rarely traveled. It’s not worth the effort. Simple as that.

Ridiculously, developers tend to focus on “make it faster” whenever they read others’ code. It’s common to read comments like “This inefficient code is horrific!” This totally neglects whether the code solves the problem on time.

There’s No Shame in Writing Trash Code

The first step is to make it work. Plain and simple.

Making things work by violating principles of good design in a quick, hacky way is completely fine.

Dreaming up premature, elaborate up-front designs is entirely useless. Exploration is best done using a few, battle-tested techniques such as prototyping, proof of concept, simple trashy code, and throwaway code.

Everything is laid out right in front of you. There are no abstractions, no magic, no “I wonder how that works.”

What’s important, though, is to recognize this as a first step. Leaving trash behind is a surefire way of building up technical debt that’ll come back to haunt you. Experiment like a mad lad, but clean up before pushing the code.

You might want to read my article on garbage code as well.

Let’s Make It Better

Time to be real: No end-user is going to be like “Man, Google’s code is so neatly structured. That’s why I use Google search!” Users couldn’t care less about how much better your code is compared to the mess you made earlier. Users care about good experiences and how easy your software is to use — not how easy it is to modify.

Bettering your code is nevertheless an important aspect of the overall quality of your product. The internal software quality affects your ability to pivot, detect and correct defects, and the time to release.

Before moving on to making your software better, be sure to somehow validate that your software is still functioning correctly after the modifications. Put in place some sort of regression testing. Unit tests are useful, but code inspection is just as important.

Making your software better is not just about refactoring. Refactoring is essentially behavior preserving changes to your codebase. But making your software better is a different species, where refactoring is only a part of it.

It’s re-architecting. Applying design patterns where applicable. Assessing if your code is SOLID. Fixing code smells and taking care of edge cases.

Better code is:

  1. Readable
  2. Maintainable
  3. Flexible

Strive to achieve these characteristics by applying modern practices as well as the famous SOLID and DRY principles. I won’t preach theory here, as there’s already an overwhelming number of articles on these topics. Just google the acronyms.

If We Ever Get Around to It, Make It Faster

Not every aspect of your application or library is created equal. Not every line of code is executed at the same frequency. Don’t rush off code tuning every line.

What you often find is only a small part of your application is using a disproportional share of the runtime. Figure out what part it is, measure its performance, set performance goals, optimize, and measure again.

Optimizing without a target performance is not going to end well. You might do some solid performance optimization, but if you spent a whole workday on it, it’s perhaps not worth it.

After you reach a certain point of performance, users’ appreciation for every millisecond shaved off is diminishing. At this point, you’re only harvesting street credit from fellow developers, which is completely pointless.

Some developers preach that you must optimize as you go. Premature optimization is just as bad as applying a design pattern prematurely.

Instead, write the simplest code possible to begin with. Then refactor, redesign, etc. and optimize only if there’s a bottleneck.

Resources

Nicklas Millard is a software development engineer in one of the fastest-growing banks, building mission-critical financial services infrastructure.

Previously, he was a Big4 Senior Tech Consultant developing software for commercial clients and government institutions.

New YouTube Channel (@Nicklas Millard)

Connect on LinkedIn

Programming
Software Development
Software Engineering
Technology
Computer Science
Recommended from ReadMedium