Encapsulation is one of those concepts that is a pillar of OOP design, and is a VERY useful tool when used in the correct context.
When to avoid
Avoid using encapsulation when interacting with other systems, objects or structs. For instance, saving a thing to a database or a file. This is NOT encapsulation, as the instantiated thing DOES NOT OWN THE FILE FORMAT OR THE DATABASE SCHEMA.
Instead, we pass off the encapsulated thing to a system which knows how to extract the information it needs to serialize the data into the format and system it’s destined for.
Yes, I’m explicitly saying that the ActiveRecord pattern is a BAD pattern and should be avoided. (unless you write Django, or Ruby On Rails, then I’m sorry to be you)
When to use
When the data you are providing access to is highly complex and needs a in code representation that the coder should interact with which lowers the Cognitive Loadfor the coder.
For instance, I wrote a MIME parser for parsing emails which presented it’s self as an encapsulated struct in golang.
This worked well, because the MIME file format WAS the thing that I needed to encapsulate. It was the complexity which I needed to hide behind an abstraction.