In most languages, there is the concept of
and other access control keywords. The intention is to restrict the usage of methods and access to
data. In a way, it is the most basic form of encapsulation. After some recent work on a few apps, I’ve
come to the conclusion that there are only two forms of access control that should be used in the world:
Most of the effort in maintaining these different forms of access control is wasted. If
you are in the position to change the code, you can modify the access control from
public with just a few keystrokes. You may have initially wanted something to be
you don’t want to accidentially leak the implementation details (even to yourself). Or you don’t trust
other code developers working on your project to use the data or methods. However, anyone who has write
access to the code can change the access control or make other code changes which break implementation
preconditions and invariants. Using
private is a small speed bump to preventing bad code.
Instead of maintaining such detailed access control, for libraries, you should use only
public and the equivalent of
internal if available.
internal means any other code in the same
module (e.g. package/library) has access to the
internal data/function. In the end, libraries
have only two forms of access control that anyone cares about.
public is for all the consumers
of the library.
internal is for implementation details that only the library authors should have
Users of your app do not care what the access control is, so let everything be
idea is that while it does not matter today, you may extract code into a re-usable module later.
So make things
internal in the app, and then go back and expose the required types/methods as
public if the
code is extracted to a module.
private, and other access control should hardly be used. There have been
too many times where I’ve seen people expose the implementation details through leaky abstractions
already. Or someone either changes the access control protection to be less restrictive or copies
private code for their uses (which can be even worse). Instead of relying on
similiar access control levels, it seems to be better to just rely on code reviews and discipline instead.
For larger code bases with more than a handful of developers, break the code base into separate modules.
Encapsulation should be done at the module/library level versus in every code file across a monolith application.
Most of the time, I do believe that actually codifying the intent behind data/methods into the codebase is a best practice, but restrictive access control is not one of them. The next time that someone (maybe even yourself) changes the access control level of code you work on, try to imagine a world with only two levels of access control.