What is the real purpose of private methods?

What is the real purpose of private methods?

Our job is not to write code without thinking, we are paid to think about how to solve the problem using code.

Every programmer has ever needed to use the private access modifier. After all, it is an access modifier that many Object-Oriented languages bring with them. But just like many other features, there are always some mistakes that can happen. So what do we talk about in this post? The goal is to bring more clarity to some doubts like:

  • Are private methods only good for dividing tasks into smaller parts?

  • When to use private methods?

  • Many private methods are a problem?

  • Are private methods considered a code smell?

The purpose of private methods

Private methods are not accessible outside the scope of the class. If you try to invoke a private method you won't be able to use it.

Imagine you build an API and make endpoints and classes available for anyone to use. But in your class let's say you chose to make all methods public, even those you don't need. But sooner or later someone is going to trust a method you wrote, let's say a method that should be internal, just for you, some low-level stuff that you hoped you could change at any time - unfortunately, now you can't because another programmer who is using your API uses that method. You can even change that method, but on the other side, the programmer using that method will have problems consuming the API. The private access modifier solves this problem. Your class will only expose methods that are needed because the private methods will help the class and the public method achieve their purpose!

We can sum it up to this definition:

By hiding methods you are reserving the right to change them.

Since private methods cannot be called from outside the same class we know that we are free to refactor as much as we want and not carelessly break any external code.

Are private methods only good for dividing tasks into smaller parts?

Much is said about long classes and long methods that do more than one thing. When the topic comes up, many say that this is the purpose of private methods. But that's not quite true, we need to remember that we can also carelessly have private methods that do many things.

If we have a class that is responsible for validating an email, a number, or any kind of object, and we choose to break its public method into smaller private methods, we have to first analyze the purpose that the class is trying to achieve. The purpose of using the private access modifier is to prevent other classes from accessing that resource inappropriately, we are telling the other components of our software to look out for their interests.

Verde Caos Visual Tecnologia Apresentação.png

When we break the public method into smaller private methods, we reduce the complexity of the readability of the code, we want to make it easier to read and understand what the purpose of the class is and what each method does. For example, let's imagine I have an object with 06 methods, all public. There are 06 different ways that other parts of my program can potentially use the class. If these methods are long, it can be difficult for other developers to read the code. If we allow all methods to be public, we can also increase the coupling of this class with others and cause other developers to create bugs. Everything is connected.

Now let's take another scenario and imagine a different object that has only 03 methods with public access modifiers. It has some other methods too, but these are private. Now, there are only three possible ways that other classes in my software can use the object.

What is the point? If you don't go with private methods, it will be a little harder to understand the objects within the software and how they relate to other objects because your public methods can probably get extensive over time as requirements change and come into the project. Today your class may have 2 public methods each with 5 lines. Tomorrow the requirement is adjusted and your two methods double the lines. Soon it may be that the responsibility of the class remains the same, that it remains cohesive, but with long public methods that are hard to read in a short time. Separating into private methods will help a lot with code maintenance!

Our goal as programmers is to make software development easier, not harder! So we can say that the purpose of private access modifiers is not only to divide up tasks within classes, but it goes beyond that, we need to make sure that the class does its job well and that its methods are written coherently. If the purpose of having private methods was only that, it wouldn't make sense, we can get the same result with public methods!

When to use private methods?

This is an interesting question, but extremely difficult to answer! But why? It should be simple, if I don't want a method to be exposed to the rest of the world and be used only by the public method of the class, I need to use private. Yes, you are right. But a lot depends on the context and business requirements, you have to pay attention to the requirements because they change. Let's go to a code example:

// This method is used in a User class

  private validName(name: string) {
    if (name.length > 0 && /^[a-zA-Z]+$/.test(name)) {
      return true;
    } else {
      throw new Error('Invalid name format');
    }
  }
}

The above method is quite clear in its purpose. But let's dig deeper not only into what it does but also into the details of the context. Imagine that the User class uses this method to validate whether the user name is valid or not. The programmer who wrote the class had to meet the requirement that every user must have a valid name. The code, or rather, the software is constantly changing, so next month now this user can choose a product or can buy a product or more. Right, but what does the product have to do with this private method? For the product the name requirement is the same, the product name must be valid! So now another programmer writes a method just like the one in the User class to validate the name of a product and leaves it as private. What ends up happening in our software as it grows? Many unit tests will be the same. Many classes will have repeated knowledge and this knowledge can never be concentrated in one class that is responsible for validating a name! This is why we need to think outside the box and analyze the context in which we are working. There are common business rules, but others are unique! We can even imagine a unique rule being a calculation that a class must perform if the payment occurs on that specific day of the month, this is of course quite different from a method that validates a string (which is the case of validName). Therefore, the fairest answer to the question, of when to use private methods, involves analyzing the software requirements and context. When these requirements are clear we know what may or may not make sense for the class and what should currently be internal to the class.

In this case, code reviews are essential, more experienced developers and the team itself together can observe and analyze whether or not it makes sense to use that private method or if there is already a class that fulfills the role of the private method that was created in the Pull Request. Then you can get an alert like, "hey I think we already have this validation in some class".

Our job is not to write code without thinking, we are paid to think about how to solve the problem using code. So we need to understand the problem in depth and then attack it.

Many private methods are a problem?

The short answer is no, for the simple fact that we can have many private methods and at the same time, they are strictly bound to serve a single purpose. But we need to be moderate and look carefully at what the class is doing when there are changes in requirements. We can ask ourselves questions and start thinking about refactoring and try to change some private methods to a class that will take care of specific validations. Again you have to think about the next programmers that might work on that class. It is also valid to ask other developers for their opinion.

We can cite an example, suppose you are working on a class in which the user has a country attribute, in the current context the business team only wants to know which country the user is from in order to register and use the platform. But after the launch of the product and success of the platform the requirements change, now the context is different and so is the requirement, the business team wants to know which country, city and zip code that user belongs to and if he is from country A there is a rule that gives a discount, but if he is from B the discount is different to use the platform. It is a big change, now we need to meet these requirements, if you choose to insert everything in the User class you will need to perform these validations that are very clear business rules, if you choose to validate everything in the User class by adding new private methods you are sure to have major headaches in the future. If you start creating private methods without thinking, you will possibly generate coupling problems in the future.

So the suggestion is to think about how to solve the problem, write the solution and if it is necessary to allocate methods that are not directly linked to that class to another class that fulfills this objective.

Warning: Taking private methods to other classes may be a good choice now, but this may change in the future, each situation is unique. So understand what you are working on and if it is logical to change and separate the private method from the class.

Knowing whether your private method does more harm than good to your code is not always easy. But the following four questions can help you get an idea:

  • Should external users have access to the behavior it supports?

  • Does the method go beyond the responsibility already assigned to the class?

  • Are there other parts of the code base that duplicate this knowledge?

  • Is it not enough to test the unity of the method by means of public methods?

Are they considered a code smell?

First, it is important to understand what a code smell is. Code smells are not bugs or errors. Instead, they are violations of the fundamentals of software development that diminish the quality of the code. Code smell differs from project to project and from developer to developer, according to the design patterns that have been defined by an organization. There are programmers who cling to the idea that having some private methods in the class would be a violation of SOLID's SRP because they think that we can extract a private method in a class. But in many cases this is not necessary, taking these methods into classes is not a sign of good code design, sometimes it can even make the software worse to understand. Using the private access modifier does not lead to a code smell. It is a feature that can and should be used but always with moderation and analysis.

But it is important to point out that private methods can lead to bad designs **if we don't pay attention. Private methods that contain logic too complex to need direct unit testing are also a sign of bad design. **Sometimes you can reduce the complexity of such methods by simple refactoring. But if this is not the case, there may be a missing level of abstraction in your code causing this problem. **So keep the problem in mind and attack the solution in the simplest way. **

Conclusion

Private methods are not the enemy of clean code. On the contrary they are incredibly advantageous for writing more readable and highly sustainable code if you learn to avoid the pitfalls we have seen throughout this post.

Thanks for reading and any constructive criticism about this post please leave it in the comments!