Skip to content

Instantly share code, notes, and snippets.

@ahoffer
Last active September 18, 2021 15:59
Show Gist options
  • Save ahoffer/d3c5fb0f7b652561edd0db1a052c68ad to your computer and use it in GitHub Desktop.
Save ahoffer/d3c5fb0f7b652561edd0db1a052c68ad to your computer and use it in GitHub Desktop.
Thank you to everyone for providing so many thoughtful and insightful answers and comments.
I appreciate your perspectives and experience on the topic. I would like to pull together the
collected wisdom and summarize. I realize that summary answers are frowned upon, but
I think it is justified in this case [Questions is on hold -- cannot post new answers]
First off, the fact a convention like “underscore means private” indicates there is a real need
to designate some state or behavior as internal. Developers needed to communicate that
component contracts and postconditions might not hold true if the internal of a component are
modified.
Reasons why access modifiers matter:
• Impact analysis. Developers can feel more confident that changes to internal state and
methods will not break code using the public methods. Thanks to Doc Brown
• Modularity. IMSoP writes that access modifiers facilitate modularity: “access restrictions is
one of many ways we write modular programs.” IMSoP makes the point: “Visibility modifiers
simply iterate the same advantage: by grouping functions and variables into classes or packages,
we can give each grouping a contract and an implementation. The number of possible combinations
reduces further, to valid interactions of classes, or packages. Peter - Reinstate Monica makes a
similar point-- Access modifiers can reduce complexity for developers and promote loose copuling.
• Documentation. Kutschkem points out that access modifiers communicate a developer’s
intention and that makes them a kind of documentation.
• Help getting started. Martin Maat reminds us that access modifier help developer use
new libraries. Start with the public classes! A good IDE like IntelliJ will even autocomplete the
public methods.
Manziel provides the best practical advice (for Java devs). My summary of his points is:
1. If an object is immutable (e.g. primitive types), make it public and final
2. Uses interfaces to implement encapsulation instead of access modifiers. It allows you
to exchange a bunch of collaborating classes without external dependencies. Access modifiers
become much less important in such a system.
3. Use constructors to pass things into an object instead of setters. Avoid trivial getters and
setters as much as possible.
I’ll add this to #1: Prefer `final` variables and immutable collections and objects to hide
information over restrictive access modifiers.
Regarding #2, if everything is referenced by its interface, you could make all methods public
and let developers downcast the object if they need to use a method. I feel that is a better
alternative to using reflection to get at the thing.
Robert Harvey reminds us that access modifiers are way to implement encapsulation.
That is fundamental point. Should code even be considered object-oriented if it does not have
some kind of access retrictions? Probably not. However, access restrictions
can be implemented in different ways. In Smalltalk, all fields are private and all methods are public.
Some Smalltalk IDEs also allow users categorize methods as public or private. Categorization
is a convention, but in my experience it was an effective one. Smalltalkers could make an
informed decision about the risks versus benefits of calling a private method or adding an
accessor to a class. In Java, I have copied and pasted code because of the `final` and `private`
keywords. How many of us have used reflection to de-privatise or un-finalize something
in Java? No one likes to do that, but who can justify forking Apache CXF and publishing your
own artifacts for something you can hack up in 10 minutes?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment