Modularization – Splitting Up Large Functions into Smaller Functions

design-patternsfunctionsmodularizationweb-development

I know function names can be very expressive. And therefore it can be tempting split up a program into particular functions and call them from a large "oversee-able" functions file.

However is this actually effective for a programmer? Since each function usually relies on some input provided from a previous function, either a returned value or a global variable or whatever else your language uses – it often only works, and makes sense in context with the previous function. A change to a previous function would often obviously destroy functionality in the second function.

When one program is split up into functions which are jumbled up into a functions file. The effect that changes have are not necessarily very clear. So is it a good idea to split things up in this way?

Best Answer

Since each function usually relies on some input provided from a previous function, either a returned value or a global variable or whatever else your language uses - it often only works, and makes sense in context with the previous function.

While I always favor compact, self-contained functions over huge, sprawling if/else trees, it is true that real-world programs are seldom as nice and neat (untangled) as we would wish. Application state (global or not) is generally unavoidable.

I believe that it is also true that there are diminishing returns to splitting things up into smaller and smaller functions. For a logical extreme, take a look at the book Clean Code by Robert C. Martin. Not everyone will agree with me, but I find many of his examples to actually be slightly less comprehensible after his refactoring. (Maybe I don't write enough Java to appreciate them?)

Having said that, I do personally believe that the function is the most powerful abstraction available to us. Sure, functions can be used incorrectly. There is absolutely nothing stopping you from writing terrible, tangled code with a bunch of tiny functions, even without those evil weapons, the global variables. But on a whole, functions are a force of goodness and light.

When practically possible, heed the standard wisdom of the crowd in creating "clean" functions:

  • Do not modify any external state within your functions.
  • A function should be deterministic: the same input must always produce the same output.

Just these two rules will avoid 90% of the most common design headaches. It also allows you to easily write tests for your functions!

Beyond that, just try your hardest to make only "clean" functions when you can. Depending on the application, this can actually be a very difficult exercise at first. But one does get better at it. As with most things, it's a real craft and it takes experience (programming experience in general and experience with that project, in particular) to get it just right.

Untangled code doesn't just happen. It's hard work and an art...and totally worth it.

Related Topic