Library API exposure (and package protection) in Scala - scala

I am currently reading "Scala Programming, 2nd ed." (OReilly 2015) by Wampler/Payne, and they mention Package Objects as a means to expose abstractions.
On p.504 however, they mention
Package objects
An alternative to finegrained visibility controls is putting all implementation constructs in a protected package, then using a top-level package object to expose only the appropriate public abstractions. For example, type members can alias types that would otherwise be hidden [...]"
Now my question is: is there a way to declare said protected package as protected once, without having to declare it for every every class/object down the hierarchy? And if so, how?
Or did I simply misunderstand the authors?
As clarification: I am currently working on a library which is supposed to expose minimal API in order for $colleagues to have to actually touch internals to make fundamental changes or to have to do configuration via config-files.
Second question: is this the right path to go? Should I maybe go another route?

Doing a little research of my own, it seems to me that it's not possible in Scala to declare a package to be entirely private. (You can check out the Language Specification here, where there is no mention of being able to qualify a package declaration with 'private' or similar)
I think what the authors are suggesting is the following, roughly translated:
Instead of using finegrained controls, such as declaring some of your class members private or protected and leaving the rest public, you could make all of the important classes in your package completely private (as in private class/trait/object P {...}). Then, you can put the important public details of the API into the package object, exposing these private innards. For example, if you need to expose a protected type, you can use type aliasing for that...

Related

Is it good practice to keep all variables and functions private in flutter?

I am new to flutter, was going through a few good practices so had a doubt about making all the functions and variables private which won't be used outside the class.
take a look here.
https://dart.dev/guides/language/effective-dart/design#prefer-making-declarations-private
refereeing to dart.dev/guides its good to use private variable because they said
"PREFER making declarations private.
A public declaration in a library—either top level or in a class—is a signal that other libraries can and should access that member. It is also a commitment on your library’s part to support that and behave properly when it happens.
If that’s not what you intend, add the little _ and be happy. Narrow public interfaces are easier for you to maintain and easier for users to learn. As a nice bonus, the analyzer will tell you about unused private declarations so you can delete dead code. It can’t do that if the member is public because it doesn’t know if any code outside of its view is using it."
But here's the thing, it all depends on your need, but remember to make security concern. It's not wrong to use private variable all over the place if you doesn't want other class access your variable, function or class.
It depends on the variable usage because if you are not going to use the variable outside of the widget then you should keep it private (Good practice [In my opinion]) otherwise make it public.
Making private is good because you can avoid variable conflict because sometimes you may have the same name variables in different widgets so if they are private then they will not conflict with each other.
Same for the functions as well.
-- This is my personal opinion you have the freedom to make your own decisions which to use.

Does Kotlin support package protected visibility?

In Java package protected access was very handy, because it allowed to write modular code. This is not possible with Kotlin unless you stick all those classes into one file and put Private on all of them or by implementing Internal in a separate Module. But I don't like this solutions. Putting lot of stuff in one file is not readable and another problem is that you cannot test any Method/Class that is not Public. Is there another solution?
No, package-protected access is not supported.
You should use internal in Kotlin. This restricts access to the same module, a logical unit of files compiled together to an artifact.
The motivation for not providing a package-protected visibility specifier is as follows, from a Kotlin developer:
The motivation for not having package protected access is very simple: it does not provide any real encapsulation. Any other module in the system can define classes in the same package as your complex independent component and get full access to its internals. On the other hand, classes with internal visibility cannot be accessed from any module other than the one where they are defined.
And you definitely can test methods/classes that have internal access: the tests of a module have full access to internal declarations of that module.

Change Scala default class access modifier

Say I have bunch of Scala classes and I want to compile and package it to JAR.
I want to expose only some limited number of classes to external user of the JAR and "hide" any other classes.
The question: How can I achieve that without explicitly specifying private access modifier for classes to hide?
The problem is that in Scala class is public by default.
The ideal solution would be some Scala compiler option that changes default class modifier to private.
I think you answered your own question. Scala provides private for exactly this usecase.

Is there any way to require methods and members to be explicitly annotated as "public" in scala?

After developing in scala for a while, I've noticed that a lot of people tend to use default visibility for methods and class members when they should really be private. I think this is usually done out of convenience and laziness and it's hard to enforce discipline to explicitly type private in all such cases.
Therefore, I'm interested in seeing if there's a way to require the use of an annotation, (for example, methods could be tagged as Public using scala.tools.nsc.doc.model.Public). Is there an easy way to require that all default visibility methods/members are tagged with such an annotation (possibly using maven or scalastyle)?

Encapsulation in the age of frameworks

At my old C++ job, we always took great care in encapsulating member variables, and only exposing them as properties when absolutely necessary. We'd have really specific constructors that made sure you fully constructed the object before using it.
These days, with ORM frameworks, dependency-injection, serialization, etc., it seems like you're better off just relying on the default constructor and exposing everything about your class in properties, so that you can inject things, or build and populate objects more dynamically.
In C#, it's been taken one step further with Object initializers, which give you the ability to basically define your own constructor. (I know object initializers are not really custom constructors, but I hope you get my point.)
Are there any general concerns with this direction? It seems like encapsulation is starting to become less important in favor of convenience.
EDIT: I know you can still carefully encapsulate members, but I just feel like when you're trying to crank out some classes, you either have to sit and carefully think about how to encapsulate each member, or just expose it as a property, and worry about how it is initialized later. It just seems like the easiest approach these days is to expose things as properties, and not be so careful. Maybe I'm just flat wrong, but that's just been my experience, espeically with the new C# language features.
I disagree with your conclusion. There are many good ways of encapsulating in c# with all the above mentioned technologies, as to maintain good software coding practices. I would also say that it depends on whose technology demo you're looking at, but in the end it comes down to reducing the state-space of your objects so that you can make sure they hold their invariants at all times.
Take object relational frameworks; most of them allow you to specify how they are going to hydrate the entities; NHibernate for example allows you so say access="property" or access="field.camelcase" and similar. This allows you to encapsulate your properties.
Dependency injection works on the other types you have, mostly those which are not entities, even though you can combine AOP+ORM+IOC in some very nice ways to improve the state of these things. IoC is often used from layers above your domain entities if you're building a data-driven application, which I guess you are, since you're talking about ORMs.
They ("they" being application and domain services and other intrinsic classes to the program) expose their dependencies but in fact can be encapsulated and tested in even better isolation than previously since the paradigms of design-by-contract/design-by-interface which you often use when mocking dependencies in mock-based testing (in conjunction with IoC), will move you towards class-as-component "semantics". I mean: every class, when built using the above, will be better encapsulated.
Updated for urig: This holds true for both exposing concrete dependencies and exposing interfaces. First about interfaces: What I was hinting at above was that services and other applications classes which have dependencies, can with OOP depend on contracts/interfaces rather than specific implementations. In C/C++ and older languages there wasn't the interface and abstract classes can only go so far. Interfaces allow you to tie different runtime instances to the same interface without having to worry about leaking internal state which is what you're trying to get away from when abstracting and encapsulating. With abstract classes you can still provide a class implementation, just that you can't instantiate it, but inheritors still need to know about the invariants in your implementation and that can mess up state.
Secondly, about concrete classes as properties: you have to be wary about what types of types ;) you expose as properties. Say you have a List in your instance; then don't expose IList as the property; this will probably leak and you can't guarantee that consumers of the interface don't add things or remove things which you depend on; instead expose something like IEnumerable and return a copy of the List, or even better, do it as a method:
public IEnumerable MyCollection { get { return _List.Enum(); } } and you can be 100% certain to get both the performance and the encapsulation. Noone can add or remove to that IEnumerable and you still don't have to perform a costly array copy. The corresponding helper method:
static class Ext {
public static IEnumerable<T> Enum<T>(this IEnumerable<T> inner) {
foreach (var item in inner) yield return item;
}
}
So while you can't get 100% encapsulation in say creating overloaded equals operators/method you can get close with your public interfaces.
You can also use the new features of .Net 4.0 built on Spec# to verify the contracts I talked about above.
Serialization will always be there and has been for a long time. Previously, before the internet-area it was used for saving your object graph to disk for later retrieval, now it's used in web services, in copy-semantics and when passing data to e.g. a browser. This doesn't necessarily break encapsulation if you put a few [NonSerialized] attributes or the equivalents on the correct fields.
Object initializers aren't the same as constructors, they are just a way of collapsing a few lines of code. Values/instances in the {} will not be assigned until all of your constructors have run, so in principle it's just the same as not using object initializers.
I guess, what you have to watch out for is deviating from the good principles you've learnt from your previous job and make sure you are keeping your domain objects filled with business logic encapsulated behind good interfaces and ditto for your service-layer.
Private members are still incredibly important. Controlling access to internal object data is always good, and shouldn't be ignored.
Many times private methods I've found to be overkill. Most of the time, if the work you're doing is important enough to break out, you can refactor it in such a way that either a) the private method is trivial, or b) is an integral part of other functions.
In addition, with unit testing, having many methods private makes it very hard to unit test. There are ways around that (making test objects friends, etc), but add difficulties.
I wouldn't discount private methods entirely though. Any time there's important, internal algorithms that really make no sense outside of the class there's no reason to expose those methods.
I think that encapsulation is still important, it helps more in libraries than anything imho. You can create a library that does X, but you don't need everyone to know how X was created. And if you wanted to create it more specifically to obfuscate the way you create X. The way I learned about encapsulation, I remember also that you should always define your variables as private to protect them from a data attack. To protect against a hacker breaking your code and accessing variables that they are not supposed to use.