While I understand the value of implementation/interface distinction, I fail to see why most OO systems issue errors on access to private members.
I indeed wouldn't want to access private members in my main program.
But I would like to have that access for tests and debugging.
Is there any good reason whatsoever to issue errors and not warnings? The way I see it, I am forced to either write code I can test, but that doesn't utilize language support for interfaces, or use the language support, but have difficulty in testing.
EDIT
For those who suggested using public interfaces. You can, but it's less convinent.
On a conceptual level I find privacy that doesn't care about who or when quite crude.
Friend classes seem like a reasonable solutution. Another might be an 'all public' compiler switch.
The way I see it, I am forced to either write code I can test, but that doesn't utilize language support for interfaces, or use the language support, but have difficulty in testing.
Why do you need to access private
variables and functions? Either they are called (however indirectly) by public
functions at some point, or they are just inaccessible pieces of code that shouldn't be there at all because there is no way to invoke them. Think about it, if the private
method is completely impossible to invoke from outside the class in any way at all, is it ever going to be run?
If you really want to test a private
method anyway, you can pull it into its own class. Plus, if its so complex that it really needs to best tested individually, there's a chance that it deserves to have its a chance in the first place. The other option is to just make it public whenever you need/want to test it, but not actually change the 'real' code (leaving it private
). As others have said, some languages also have features that help you test these methods by exposing them slightly more, such as friend in C++, internal in C#, and package-private in Java. Occasionally the IDE's themselves even help out.
Is there any good reason whatsoever to issue errors and not warnings?
One big reason is not so you can't call them, its so other people can't call them. Picture this, you're writing a library that's going to be used by a substantial number of clients. You've marked everything they shouldn't need to call private
, and all the functionality they do need is public. Programmers go ahead and start using your library, write a bunch of code with it, and produce happy customers both out of themselves and their own clients.
A few months later, you decide to spice up your massively successful library, and find that you need to do a bit of refactoring. Hence, you [rename, add/remove a parameter from, delete] some of your private
methods, but are careful to keep all of your public method's interfaces exactly the same to make upgrading a seamless process. BUT in this universe, compilers only issue warnings and not errors when you access a private
variable, and several of your client programmers wrote code that calls those private
methods. Now, when they try to upgrade to your new version of your library, they get a bunch of real errors because they can't call those private
methods anymore. Now they either have to spend time finding out what went wrong with the code and rewrite potentially large parts of it that they don't remember anything about (did I mention that this is two years in the future?). Hence, they have to completely relearn how to use your library and rewrite their client code, which is far from fun for anybody. Now they're rather displeased that you were so inconsiderate as to literally break all of their code with your upgrade and make their lives far more difficult.
Guess what, when they were fixing the code, they researched and called your new private
methods, so if you ever decide to change their interface when you issue an upgrade, the whole cycle starts over again. What was slightly more convenient for you just got you a bunch of unhappy customers.
Wait, weren't they idiots for calling my private methods? Why didn't they look at the warnings? This is their fault, not mine!
Well, yes, it is their fault and they could have prevented the problem by taking care to note those warnings. But not everybody is a code-quality fanatic who wants to fix and understand warnings, and a substantial amount of people just ignore them. The thing is, you could have prevented the whole thing yourself if compilers issued errors for trying to access private
variables and methods instead of warnings, because otherwise the private
keyword might as well not exist at all. You may have lost a little time because those methods are harder to test, but you have gained the power to keep less intelligent people from misusing your code and blaming you for any problems it causes them down the road.
One of my favorite tenets of software development (and product design in general) is that things should be easy to use correctly and hard or impossible to use incorrectly. True private members are the embodiment of this advice because they literally make your code impossible to use correctly.
[hypothetical retort:] Well, the people using my code should be smart enough to figure it out. All I'm asking them to due is just spend a little extra time to use the code correctly.
So you are consciously refusing to spend the time necessary to improve the quality of your code and make it easier to use? Then I don't want anything to do with what your code. Obviously your time is more important than that of your clients, so I'll take the 2.5 seconds it requires to close the web page for your project and click on the next Google result. There are a lot more private
members of the libraries you use than you might think, and the glorious thing is that you don't have to spend even a millisecond of your time worrying about them because they're totally hidden from you and would only distract from the easier and better way of doing things that is provided in the public
interface. If everything was public or wimpy-warning-issuing private, you'd have to sift through a greater amount of functions before you actually found what you wanted.
Whenever you type private
before a member function, you have just given yourself the power to change it in any way you want at any point in the future because nobody can touch it but you. The second someone else tries to access it they will get a show-stopping error because the compiler has your back and won't let them do anything stupid with your code when you've already provided perfectly everything they need in a much more usable form in your public
interface.
Yes, it will make it slightly harder to test in the now, but it has also ensured that you won't have to worry about it in the future when you refactor and made your code a lot easier for other people to use. Go ahead and make it public temporarily (I kind of like your 'all-public compiler switch idea :), but don't forget to switch it back when you're done you and your clients can all have the joy working with simpler and more adaptable code. :D