Can There Be Too Many Private Functions or Methods?

code-qualitydocumentationprogramming practices

I understand the importance of well documented code. But I also understand the importance of self-documenting code. The easier it is to visually read a particular function, the faster we can move on during software maintenance.

With that said, I like to separate big functions into other smaller ones. But I do so to a point where a class can have upwards of five of them just to serve one public method. Now multiply five private methods by five public ones, and you get around twenty-five hidden methods that are probably going to be called only once by those public ones.

Sure, it's now easier to read those public methods, but I can't help but think that having too many functions is bad practice.

[Edit]

People have been asking me why I think having too many functions is bad practice.

The simple answer: it's a gut feeling.

My belief is not, for one bit, backed by any hours of software engineering experience. It's just an uncertainty that gave me a "writer's block", but for a programmer.

In the past, I have only been programming personal projects. It's just recently that I moved on to team-based projects. Now, I want to ensure that others can read and understand my code.

I wasn't sure what will improve legibility. On one hand, I was thinking of separating one big function into other smaller ones with intelligible names. But there was another side of me saying that it's just redundant.

So, I'm asking this to enlighten myself in order to pick the correct path.

[Edit]

Below, I included two versions of how I could solve my problem. The first one solves it by not separating big chunks of code. The second one does separate things.

First version:

public static int Main()
{
    // Displays the menu.
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

Second version:

public static int Main()
{
    DisplayMenu();
}

private static void DisplayMenu()
{
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

In the above examples, the latter calls a function that will only be used once throughout the program's entire runtime.

Note: the code above is generalized, but it's of the same nature as my problem.

Now, here's my question: which one? Do I pick the first one, or the second one?

Best Answer

Now multiply five private methods by five public ones, and you get around twenty-five hidden methods that are probably going to be called only once by those public ones.

This is what is known as Encapsulation, which creates a Control Abstraction at the higher level. This is a good thing.

This means that anyone reading your code, when they get to the startTheEngine() method in your code, can ignore all of the lower level details such as openIgnitionModule(), turnDistributorMotor(), sendSparksToSparkPlugs(), injectFuelIntoCylinders(), activateStarterSolenoid(), and all of the other complex, small, functions that must be run in order to facilitate the much larger, more abstract function of startTheEngine().

Unless the problem you are dealing with in your code deals directly with one of those components, code maintainers can move on, ignoring the sandboxed, encapsulated functionality.

This also has the added advantage of making your code easier to test.. For instance, I can write a test case for turnAlternatorMotor(int revolutionRate) and test it's functionality completely independent of the other systems. If there is a problem with that function and the output isn't what I expect, then I know what the problem is.

Code that isn't broken down into components is much harder to test. Suddenly, your maintainers are only looking at the would be abstraction instead of being able to dig down into measurable components.

My advice is to keep doing what you're doing as your code will scale, be easy to maintain, and can be used and updated for years to come.

Related Topic