By David Budworth, Chief Architect, Apex Fintech Solutions
At a moment when everyone who can work remotely is doing so, simple software design—software programs with simple logic and easy-to-read code—are more important than ever. Lean software designs result in robust systems that are easy to understand and maintain over time.
This understandability extends the longevity of your software systems, improves engineering productivity, and makes your continued work an investment in technology for the future.
Try to strive for a single command to build and run our whole system on a laptop, which saves time and minimizing our developers’ time and effort configuring any aspect of it. During this pandemic, we are hiring new software engineers that we’ve never even met face-to-face and quickly getting them up and running on our system without ever having been in the same room. Our focus on simplicity makes this possible and reduces overhead that more complex systems require. The more complex your system, the harder it is for a developer to build, to add features and to keep software up and running.
In our experience, a key element of simplicity is starting with the right tooling to edit, compile, test, and prepare software for release. If you get the tooling right from the start and make it easy to work with your code base, developers can spend the majority of their time on what they do best—designing and engineering software.
At the same time, they can minimize time configuring and struggling with your existing systems.
Here are some tips for getting started with simple design.
1. Start every project with a makefile.
A makefile is an input file for the tool Make, one of the original build tools, created in 1976. Think of it as a slightly smarter version of just running commands from the command line or a shell script. Yes, there are much fancier tools out there for building software, but with the bells and whistles come a lot of complexity and a steep learning curve. Our job isn’t to craft and troubleshoot complex builds; it’s to solve complex problems, so we should use the simplest build tool that is sufficient for our needs. Makefiles have been around forever and generally just work.
2. Automate third-party dependencies and runtimes.
These can be databases and messaging platforms like PostgreSQL and Kafka. Doing this has been greatly simplified by programs like Docker, where you can set up all your dependencies and use docker-compose to download, launch, and clean things up. In some cases, where you want to test with higher volume data but are working on your Mac, Docker can have too much of a performance impact. In those cases, we build our own tool to manage the MacOS native versions of these apps. It is slightly more complicated, but still gives you a simple “make tp” command to launch our third-party items. This allows our developers to focus on building systems rather than installing, configuring and managing others’ systems.
This automation also requires being able to reset these third-party dependencies. We have a “make tpreset” command that will clear the database or reset Kafka topics. This allows us to reset to blank to try to isolate problems. If you had to manually reset everything, how much time does that waste in your development/test cycle? We generally have a goal of no more than 10 to 30 seconds between runs. To accomplish that, we have to automate the reset, rebuild, and restart of these dependencies.
3. Run your entire system locally.
Independent workflows and verifiability are the productive team’s secret weapons. If your system is able to run locally on your computer, each engineer is able to make changes without affecting all other developers working in the system at the time. By contrast, in a shared system, a change such as adding a column or renaming a field risks breaking the environment for other developers and slowing down your whole team’s progress. That will discourage people from making bigger changes or testing new ideas for fear of impacting their colleagues. But when it’s all on your laptop, you can change the name of that column, drop that table, do whatever you want, run it locally, see that it works, and keep your change moving toward becoming part of the code base.
Having a single command to start everything makes future changes that much easier, as no one has to reconfigure or relearn how to run the system. Moreover, when it’s easy for your code reviewers to run your changes, regardless of what changed in the system, you can achieve higher quality reviews.
Simplicity in software design and simple, effective tooling make it easy for people to understand and work with your code base.
If the only people who can understand and run your system are the people who built it—whether that was 20 years ago or 20 minutes ago—it’s bad for software engineers and it’s bad for the business.
Are you a fearless technologist who appreciates clean code? Explore opportunities with our team.