Source: https://dzone.com/articles/mark-your-safe-zone-utilizing-access-modifiers
Mark Your Safe Zone! Utilizing Access Modifiers in Java
by Mateusz Winnicki
A vast majority of methods and classes in Java are marked as public. Check out this post on one developer's thoughts on public classes and why it is unwise.
Recently, I was wondering which keyword
in Java is the most used by programmers. Is it final, return, class, or
maybe something else?
Unluckily, I haven’t found any broader statistic on the
Internet or even on GitHub. However, I remained curious, and so, I wrote
a simple file crawler and ran it on several big projects found on
GitHub. The outcome was horrible.
Three of the most used keywords in projects that I noticed are — in order — public, final, and, lastly, return.
I agree that final and return can be used in almost every
method and class in our programs, but I cannot believe that public is so
common, let alone the most used method.
A bell went off in my head — something is wrong. Why is the
public access modifier so heavily used? I checked projects one more time
only for access modifiers:
- Public — 80%
- Private — 17%
- Protected — 3%
Unfortunately, I couldn’t check the default scope, as it has
no keyword, but based on a number of classes in projects, I checked and
can tell that the default scope count will be similar to the protected.
So, the number is very little — too little!
What does it mean that almost everything is public in our
code? Is it bad or is it good? Well, it is definitely not good. It is
actually awful and can lead to many cases of abuse.
Why Is Public a Bad Thing?
First, we should consider why this problem occurs. My main
guess is modern IDEs. Modern IDEs, like IntelliJ or Eclipse, are
creating a new class by default with the visibility set to public. But,
should they? Don't we already have a default modifier that is no
modifier? I think that the creators of the Java language tried to save
our time from writing new classes by making that. If the majority of
classes and methods will be set to the default, why do we need to assign
a modifier to them? I guess that was the question that they asked when
they were creating the Java Language Specification.
Another option is that programmers actually don’t know how or why we should use a default modifier. Unfortunately, this leads to problems that static analyzers have the option to warn on the usage of default/protected modifier, which is really disgusting!
Another option is that programmers actually don’t know how or why we should use a default modifier. Unfortunately, this leads to problems that static analyzers have the option to warn on the usage of default/protected modifier, which is really disgusting!
Ok, but why is public so wrong? Why can’t we just make everything public?
Because we should always respect the privacy of our code.
For example, we respect the privacy of our friends, colleagues, and we
want to keep our lives private. It is as simple as that.
But, something needs to be public, right? Yes, there is a
public function in programming called an API. An API has to be public
because the parameters of an API have to be public. Everything behind
the API, however, has to be made not public. Of course, I am not talking
about the API of our whole application. I am talking about the feature.
What is the default modifier in Java? The default modifier
is a package-private visibility, which means that nobody outside our
package can directly use this field, method, or class with that
modifier. This approach is commonly used in the package-by-feature or
hexagonal architecture in contrast to dividing code by layers or themes.
What Steps Need to Be Done to Create a New Feature?
We need to:
- Define the public API of your feature
- Write tests for your public API
- Implement public APIs using many, many internal classes and methods (with the default or private modifier)
It makes no difference if we are talking about
service-oriented applications or object-oriented applications. We can
almost always break it down.
Let's look at an example: you want to expose a feature using
the SELECT clause on the SQL database. In a standard way, there will be
a public driver that will have direct access to the database, and with
it, you can call anything from anywhere. Do you want to drop the
database directly from the front-end? No problem. In this way, you will
have a public API for the database, which will expose methods with
SELECT. There won’t be an easy way to expose the whole database.
Anyone who wants to use your feature will have to access
your public API to do so. Are you using database inside? No problem —
nobody will be allowed to access it directly and corrupt your state. Are
you calling the external system inside your feature? Still no problem;
nobody will have access to that.
What Are the Benefits of This Approach?
You have a big control over your code, and as long as your
public API will fulfill a contract that long, you can do whatever you
want inside. You can easily refactor your behind-API code, you can
divide classes, extract additional methods, breaking down
responsibilities, and you will not need to think about the outside
world.
Your code is easily testable; you wrote tests for your API,
and now, you have a big regression suite to avoid problems in the
future. Moreover, your tests are a documentation on how to use it. Keep
in mind: noone forbids writing tests for your nonpublic classes. It is
all right to do it when it is needed. In an example, when you have to
test your super complicated algorithm or regex, it can be more
complicated for testing it through the API. Just remember to not attach
to this class and test. At some point, you need to delete it and forget
that you ever wrote it.
As your inside classes are not accessible by the outside
world, your whole solution is characterized by high cohesion. All you
have to do is stick to a contract and you will be fine.
From a user perspective, all your features will be easily
accessible and usable. Nobody will have to check all the codebase to
know what is going on. Just look on packages and public APIs.
I don’t know why the majority of classes are public, but I
know why it is a bad thing. Remember, once you expose all your classes,
it will be difficult to remove them from the system in the future, as
everybody can use them directly. Next time, when you are creating a new
class, think and consider if it is necessary to make it public.