Hacker News new | ask | show | jobs
by spivey 5808 days ago
I sympathize, yet encapsulation is appropriate for some projects. Not all users of a library want to frequently update to their own code. Forbidding encapsulation and deprecation would increase this cost. Also, it's comforting to be able to refactor the guts of a class without harming users.
2 comments

The issue is less about encapsulation and more about language-enforced encapsulation. Encapsulation is good, but encapsulation that's enforced by the language is debatable.
If the language isn't enforcing the encapsulation, how is it encapsulated?

For me, encapsulation comes down to "What I hide, I can change. What I expose, other types may couple to in an inappropriate way."

> If the language isn't enforcing the encapsulation, how is it encapsulated?

What do you mean by "enforce"? Java's private modifier doesn't enforce encapsulation. Javascript's objects do not have a private modifier, but still provides encapsulation via closures. It's hard to have a meaningful discussion when loose terms like "enforce" are thrown around.

Sure, the private access modifier doesn't strictly "enforce" encapsulation. Perhaps the term should be "language supported".

I guess, for me, that the point of private is to clearly communicate the intent of the interface (small "i" interface) of a type. That intent is generally "don't use this, use this other part instead" or "if you couple, to this, it may break on you".

There are other ways of expressing that intent, I just really like having the compiler help me and my collaborators from making stupid mistakes.

Most dynamic languages use convention, which seems to work pretty well in practice. My take is that if other developers are accessing the encapsulated parts of your library, then your API or your documentation is broken - possibly both - and you should, like, fix that. Not use language features to lock them out.
One of the things that I have used access controls for is to simplify the exposed surface that collaborators work with. This isn't a condescending "I don't trust you" intention. It's more along the lines of "of all the types and methods here, you only need to know about this small subset". It's customer service, I tell ya!

And if the API isn't sufficient by not exposing enough, that's fine. It's always easier to expose something later than to make it private later.

Maybe easier for you (very debatable), but never easier for the guy who needed something exposed today to get his job done.

I have never been bitten by over-promiscuous code entries in Python. The times I've gone beyond the published API, I knew I was doing it so I knew I had to keep track of it. And I've gone deep here (replacing Django's database handling in their unit testing framework).

On the other hand, I can't count how many times I've been stuck in Java figuring out how to get around somebody's final class or private method that I really needed to tweak just a little bit or, worse, I needed access to a field I can see in my debugger. Needing to reflect through to get at it is STUPID.

You may have a planes-that-crash bias there. You don't notice all the times you benefit from a well encapsulated service because it just works the right way. The rare handful of times when something that would be useful is marked private is what sticks out in your mind.

I know that I would prefer to work with an interface with 10 public classes with 50 public methods than an interface with 100 public classes with 5000 public methods.

The conceptual weight of wading through all of that stuff has a cost. There is often value in not knowing or caring about implementation details.

Although I do agree that final/sealed is generally just mean-spirited and pointless.

> It's always easier to expose something later than to make it private later.

...if you're using Java, since (AFAIK) you can't switch between public fields and getters/setters. Python, however, has properties: http://www.python.org/download/releases/2.2.3/descrintro/#pr... . Point 4 of http://dirtsimple.org/2004/12/python-is-not-java.html covers why they're a good idea, though you can probably figure it out from their description.

Yes, I do a lot of work in C#, which has properties that are code-compatible with public fields. The last time I did a Java project, I was surprised at how much I missed them.
Encapsulation is completely orthogonal to access modifiers.
Your view differs from some of the OO language designers. For example, Stroustrup defines encapsulation as "the enforcement of abstraction by mechanisms that prevent access to implementation details of an object or a group of objects except through a well-defined interface. C++ enforces encapsulation of private and proteced members of a class..."

http://www2.research.att.com/~bs/glossary.html#Gencapsulatio...

Since this idea is not obvious, would someone mind explaining?

Every useful software engineering term is actually undefined, until you define it for the purpose of some discussion. Encapsulation, strong typing, object orientation, you name it, it's undefined. By undefined I do not mean "completely without meaning", but that the term is used so many ways that the information content of pointing at something and calling it "encapsulation" is actually very low.

Some OO traditions choose to combine encapsulation with language-enforced access control. Some schools then teach that if you don't have enforced access control, you don't have encapsulation. They're right... by their definition. They are not right by all definitions. If you don't lay out the definitions you are using when you explain whether one is necessary to the other, you're just making undefined statements. And usually one will be related to the other by definition, which means the other basic alternative is to make a vacuous argument.

I say that like a lot of other things that are mistaken as language features, encapsulation is an attribute of the program, not the language. Encapsulation is when there is a clear boundary of code that accesses a certain data structure. I have seen many C programs that have perfectly well encapsulated data structures, despite the lack of language support for access control enforcement. But that's just my definition. It is not the definition.

> Your view differs from some of the OO language designers.

Oh come on, that's not true at all. C++ just happens to use access modifiers to provide its brand of encapsulation. However, languages without the `private` reserve word can still provide encapsulation -- they're not the same thing.

What if Java had no notion of private? It would be very difficult to provide data hiding (not that they're hidden anyway, but that's beside the point), so instead you would be forced to put little flags on your names and warnings in your documentation delineating the parts that people shouldn't touch. If they did then that's their fault no?

Encapsulation can be achieved quite efficiently if you have closures ... you can have good encapsulation (i.e. preventing access to the implementation details of an object) even in Javascript.

Many dynamic languages also have tools you can use to make your life easier ... with Python I'm using pylint/pychecker to keep me honest. My Emacs instance screams at me whenever I access a protected field of some object.

Also ... private/protected fields or final classes have caused much trouble for me. Overriding the behavior of a class is the easiest way to workaround various bugs without modifying the original source ... which in some cases is a PITA, while in other cases is impossible.

I once worked on a Java project that used a commercial library with no source-code ... to fix a stupid bug I had to manipulate the bytecode at runtime. Which shows again that private/protected/final access modifiers are pretty useless as guarantees ... a determined developer can get passed them.

It's just that you begin to hate life a little bit more.