7 rules for writing programs that will not die with you

Original author: @karangoel.
  • Transfer
Your programs are your legacy. Decide for yourself how long it will last.

Life ends, but programs do not have to die.

After a series of my tweets on how to write programs, I was asked to expand on this topic. I warn you that rarely in which project is it possible to clearly follow all seven rules. I myself often do not succeed. But the more rules you follow, the more your programs will live. Each symbol adds something to the overall ecosystem, and our task as engineers is to keep the ecosystem clean and tidy.

What can be obtained by issuing good code? Doesn’t the right to life approach to learning called “move faster, breaking everything in your path?” No. Learning to write code is a skill, it is available to everyone. Learning to write good code is an art. It takes effort, time and determination.

Do you really want to leave even more SEGFAULTs to the world after your death ? Do you want system administrators to fix systems that break because of your shitty code? So that your project manager remembers you as an engineer whose work infuriated users?

There is nothing wrong with quickly moving forward, but at some point you need to realize that low-quality code will not take you far.

When you go to the doctor, he first asks you a lot of questions to understand what happened to you. He does not prescribe medication before making a diagnosis. Similarly, it’s important to figure out if something is really wrong with your code.

1. Does rolling updates take a lot of time and effort?
2. Does the system crash even with a small update?
3. Have you ever rolled out a broken code for production, and this only became known after user complaints?
4. Do you know what exactly needs to be done when the system crashes? How to get to backups and recover from them?
5. Do you spend more time changing environments, re-executing the same commands, running some utilities - than writing the programs themselves?

If you answered yes, this article is for you. Read, but rather read twice.

1. Divide into modules

The human brain is a complex device, more complex than any processor , while it does not cope with solving complex problems. Let's say it's hard to immediately multiply 13 * 35. But if you divide these operations into simple ones: 35 * 10 + 30 * 3 + 5 * 3 = 455, then the calculation is simplified. Dividing the task into simple and independent, we come to the answer.

So it is with programs. Break the program into several parts, files, directories. projects. Print all the dependencies in one place, use the MVC principle or its variant. Such code is easier to read and easier to debug. In most cases, debugging will lead you to several lines of code, and not to a file of thousands of lines. Rolling updates of one module, you will not break the rest of the system.

2. Test

Fu, tests. Brrrrrr!

Such a reaction is natural because we have been taught that tests are not part of programming. You are taught patterns in C ++, but not how to test them. That is the problem. Some believe that tests are over writing until the program itself.

I don't care when you write tests, if you write them. No need to be heroic, start with a simple one (print (add (1, 1) == 2)), and then go to the test framework in your language.

Then you will begin to understand the complexity of your program, learn to divide it into modules, parts that can be tested separately. It turns out that using the tests, you will already fulfill two of the seven rules.

3. Continuous integration

Tests should be successfully completed, and in different environments (for example, in different versions of Python). Also, tests should be carried out after each change. Instead of doing it manually from the command line, it’s more convenient and faster to create a platform for continuous integration.

Continuous Integration (NI) is a development practice in which code is integrated into the repository several times a day. Each time it is checked automatically, which allows you to track problems at an early stage.

For my projects I use TravisCI and Drone.io . When I make a new addition to the code, the platform builds and runs tests.

4. Automate

Large projects always have a bunch of minor supporting tasks. Some people make texts with teams and copy them from there. But it’s easier to learn bash scripts (and / or Python). Here are some tasks that need to be automated with scripts:

- converting README.md to other formats
- automatic testing (including creating test servers and data, deleting temporary files, etc.)
- uploading code to the development server
- placing the program on production
- automatic dependency update

5. Redundancy

The first thing you see on git-scm.com:

Git is a free distributed open source version control system designed to work with both small and very large projects, with high speed and efficiency.

Distributed. This is a keyword. Pinch yourself if you are hosting only on a github. Because it is a single point of failure. If the github crashes, or during the push operation you damaged files, your development process stops.

Log in to Bitbucket and do the following in your repository:

# rename origin remote
git remote rename origin github
# add the gitlab remote (for the love of everything that’s holy, use ssh)
git remote add bitbucket 
# push existing code to new remote
git push -u bitbucket —all
# let’s magic
git config -e
# add this in the file
[remote “origin”]
url = git@github.com:username/reponame.git
url = 

Now, when you upload the code, the changes are going on both Github and Bitbucket. You never know when something will break. And it’s always useful to have backups. Here's how it works for me:

- all the code lives in the Codebase directory in Dropbox. Auto sync.
- Almost all of the code lives on Github
- the most important code lives on two private mirrors - one at school, the other on my AWS.

I will lose my code only if the world ends.

6 commits

This should be familiar to you. Take a look at the story and you will see something like:

"Fixed a bug in the module"


Corrected? What is the mistake? In which module?

Many regard the version control system as a backup, and not as a way to keep history. The story of such messages is useless. Suppose you decided to return something a week after this commit, because it introduced a new bug into the project. But since there is no description of the action, you need to view all the changes. To prevent this, version control systems were created.

In order not to strain, just use the following clipper:

- Each commit should have a meaning. Bug fix, add new function, delete existing?
- only one change per commit
- include the problem number in the commit message
- include a description of the changes. It depends on the rules of the current project, but usually you mention what led to the error, how you fixed it and how to test it
- write a meaningful message:

added a new form to the header to make it easier to collect links. closed # 3


deleted everything, for why not, heh

7. Plan

Even if you follow all the previous rules and feel like a programming god, anything can happen anyway. Have a plan for the worst case. What if traffic breaks records? Where do you get backups if the system crashes? Who should call at night if the server is screwed up?

Think over, but don't overdo it. Automate everything that is possible. Then document everything in detail. So that whoever receives your code can also follow the plan. Having a plan does not only mean looking smarter, it means really being smarter.


These are the rules that determine a good program. If they have not convinced you, answer me two questions:

1. Do you expect from a newbie who has joined you that he will understand the existing code with ease?
2. Is code refactoring simple and quick?

If not, re-read it again. Save, share with the team.

These rules may seem obvious at first. And there is. Bad code is constantly being created, and in the end, it dies. Your programs are your legacy. Decide for yourself how long it will last.

Happy programming.

Also popular now: