I have just recently switched from Java to Kotlin for microsevice implementation. I like the language but the absence of package private visibility is what discourages me the most so far.
I’m surprised no one yet mentioned anything about two major practices for structuring your code: package by layer vs package by feature. This article describes the subject really well: Java Practices->Package by feature, not layer
So what you Kotlin team did is made all the people who use package by feature to structure the code quite unhappy.
Basically i want my package to become my second most primitive module unit after the class itself. Package scope (visibility) is an essential unit for code modularization and you have thrown it away making package a mere unit for structuring physical files.
The thing is, these modifiers are visibility modifiers. Not access modifiers. They don’t provide encapsulation - there’s no real encapsulation in OOP. They let you constraint the code visibility. And we are using that to express ourselves. Not to protect our code from being accessed. Yes you can access my code and i’m ok with that because you can only do that in an unnatural way implying that you shouldn’t be doing that in the first place.
- This is not about encapsulation - this is about modularization by means of visibility constraints
- This is about the design, about being able to draw the line while structuring your program
- This is the second most simple and one of the most important methods for modularization in Java, enforced by the language designers by default
- No package scoping in the language forces us to make all of the package private classes private staffed inside the single file which is just bad
- No package scoping in the language provokes the pollution of the classpath rendering code autocompletion useless
- internal visibility modifier is useless when you work on the same codebase and has no actual value in this context thus can’t be considered as package private replacement
- The larger the codebase the more of the problem absence of the package scoping really is
I don’t need to protect my code. I want to express myself. I want to hide implementation details in my package to make my design and intentions clear to others and to myself when i revisit the codebase.
With package scoping i can design the module around the package exposing only it’s public API and leverage DI framework to actually wire the “package modules”. If my package grows i separate it into the actual module or even microservice of it’s own. When i use DDD with “package by feature” i can naturally implement everything related to one aggregate root within single package and later make that a separate microservice without much effort.
Please, Kotlin team, reconsider this and incorporate the package visibility scope into the language.
I couldn’t agree more.
package private was very cleverly chosen to be the default scope. And Kotlin throws it away making everything wide-open by default. And internal is the same “wide-open” in the context of a single code base. Most of the classes we write are an implementation details related to the package we are in so public isn’t suitable as the default scope, is it?