Robert’s Rules of Coders: #1 Write Subroutines Profusely
Posted by robkraft on August 1, 2015
Most programming languages support the concept of a subroutine. A subroutine is a block of code that your current code calls (aka executes) to run some more code. Subroutines are called by many different names, with some of the most common being ‘function’, ‘method’, or ‘procedure’.
Subroutines serve two primary purposes:
- They allow you to easily reuse some of your code
- They organize your code, making it easier to read and maintain.
A program without subroutines
A program with subroutines
The advantages of the program that uses subroutines include:
- The code is easier for another person to read, and that other person could be the future you.
- Code that is re-used provides these benefits
- You spend less time writing code because you can use code that already exists, the subroutine that you wrote.
- The subroutine is already proven to work when used the first time. You won’t have to spend time fixing logic errors and typos each subsequent time you want to do the same things.
- If you discover a bug in the subroutine you can fix it in the subroutine which fixes it for all places from which it is called. In the first program above, if you found a bug formatting Item1PriceOut the same bug would probably also exist in formatting Item2PriceOut and need to be fixed there too.
- If you decide something should be changed, such as using “<strong>” instead of “<b>” when formatting your string you can make the change once instead of making it in several places.
- You can optimize the code later. Perhaps you later learn that you can call ConvertToDollars() and the formatting to two decimal places will be handled for you. You can make the change in the subroutine instead of making the change several times as you would have to do in the first program above.
- The subroutine is more likely to be testable from an automated test. Many languages allow you to write “unit tests” that can be run regularly to insure your code keeps working as intended even after you make changes to it over time. It is easier to unit test code isolated in a subroutine than it is to unit test code that is just part of a larger code block.
- Example Unit Tests:
- Assert.That( FormatForOutput(7) = “$7.00”)
- Assert.That( FormatForOutput(7.1) = “$7.10”)
- Assert.That( FormatForOutput(555) = “<b>$555.00</b>”)
- Example Unit Tests:
- The size of the code is usually smaller when using functions, taking less disk space.
- The size of a compiled version of the program is probably smaller, taking less disk space.
- The size of the program in memory is probably smaller, using less RAM.
- The memory allocated to variables is more likely to be re-used which therefore requires less RAM.
Use Subroutines Profusely
I recommend using subroutines when you see that you have two or more lines of code that are the same over and over in the program. One thing that makes a programmer a good programmer is the ability to see patterns. So even though these lines of code are not the same, a good programmer will see that there is a pattern and extract that pattern into a subroutine:
In this case, the second program has more lines of code, but if you need to modify Item3PriceOut and Item4PriceOut the program with subroutines will become the shorter program. And it will be easier to maintain.
Use Subroutines to Hide Complexity and Third Party Dependencies
Use subroutines for anything that might change and is used more than once, especially third party dependencies. For example, if you use a third party tool called 123Logger in your code like this:
Replace it with code like the following because if you ever want to change to a different logger than 123Logger, you will only need to change your code in one place. You are writing your code so that it is not as dependent on how the third party logger software needs to be called.
When you decide to use XYZLogger instead of 123Logger, you can change your code to look like this:
There are even better ways to handle third party dependencies like this for larger applications, but this approach is a good start.