Coding Style – Are Private Methods with a Single Reference Bad?

coding-stylereadability

Generally I use private methods to encapsulate functionality that is reused in multiple places in the class. But sometimes I have a large public method that could be broken up into smaller steps, each in its own private method. This would make the public method shorter, but I'm worried that forcing anyone who reads the method to jump around to different private methods will damage readability.

Is there a consensus on this? Is it better to have long public methods, or break them up into smaller pieces even if each piece is not reusable?

Best Answer

No, this is not a bad style. In fact it is a very good style.

Private functions need not exist simply because of reusability. That is certainly one good reason to create them, but there is another: decomposition.

Consider a function that does too much. It is a hundred lines long, and impossible to reason about.

If you split this function into smaller pieces, it still "does" as much work as before, but in smaller pieces. It calls other functions which should have descriptive names. The main function reads almost like a book: do A, then do B, then do C, etc. The functions it calls may only be called in one place, but now they are smaller. Any particular function is necessarily sandboxed from the other functions: they have different scopes.

When you decompose a large problem into smaller problems, even if those smaller problems (functions) are only used/solved once, you gain several benefits:

  • Readability. Nobody can read a monolithic function and understand what it does completely. You can either keep lying to yourself, or split it up into bite-sized chunks that make sense.

  • Locality of reference. It now becomes impossible to declare and use a variable, then have it stick around, and used again 100 lines later. These functions have different scopes.

  • Testing. While it is only necessary to unit test the public members of a class, it may be desirable to test certain private members as well. If there is a critical section of a long function that might benefit from testing, it is impossible to test it independently without extracting it to a separate function.

  • Modularity. Now that you have private functions, you may find one or more of them that could be extracted into a separate class, whether it is used only here or is reusable. To the previous point, this separate class is likely to be easier to test as well, since it will need a public interface.

The idea of splitting big code into smaller pieces that are easier to understand and test is a key point of Uncle Bob's book Clean Code. At the time of writing this answer the book is nine years old, but is just as relevant today as it was back then.

Related Topic