This way if I had to change some functionality I didn't need to change it everywhere, just in one place.
Now I'm instinctively doing the same with public functions in my classes but the more I think about it the more I think this is unnecessary.
If your public method only contains one private method call (which passes any parameters through blindly), and this private method call is only called from that one public method; then the added layer is irrelevant. The public method is just a passthrough to get to the private method.
You can simply make the private method public and it will work the exact same way.
If the public method only contains one private method call (which passes any parameters through blindly), but the private method is called from multiple locations, then the same answer still applies. The public method is just a passthrough to get to the private method.
You can simply make the private method public and it will work the exact same way. All calling locations will still be able to access the method. If you keep this public+private setup,
If the public method has other responsibilities (e.g. validation checks, collecting the input parameters to be used in the private method, calling multiple private methods, ...) then separating the private method from the public method makes sense, as they each have their own responsibility. The public method is not just a passthrough to get to the private method.
In short: You can remove the public method layer if its only job is to blindly pass through to the inner private method. Empty wrappers have no purpose*.
Is there any standard or good practice for this case in particular?
Don't add something to the codebase if it doesn't add value to the codebase. Passthrough methods (= methods which merely provide access to a private method within the same class, without any additional responsibilties) do not have any inherent value*.
*The one fringe exception here is that if you're dealing with a method in a class that implements multiple interfaces, in which the method can be used for both interfaces, but the two interfaces define a different name for this method, then you will be required to make
SecondInterfaceMethod a wrapper method around
FirstInterfaceMethod (or vice versa, or have them both pass through to a third private method) in order to comply with both
SecondInterface. But this is not a common scenario to encounter.
In this case, you can argue that "fulfilling the other interface contract" is sufficient value for the passthrough method to no longer be considered irrelevant.