Let's talk about another Pillar, Encapsulation.
Encapsulation, also known as
Information Hiding, is a concept that conveys the notion that hiding 'data' inside objects keeps them decoupled from the rest of the system. The object manipulates this 'data' within its own boundaries; that way, the system is robust in the face of
change. We already saw that Dependency Inversion is instrumental in keeping objects decoupled, acting as a kind of intermediate layer for them to communicate with each other, but this won't do you any good if the abstractions that the objects represent
leak.
Joel Spolsky talks about this concept in this marvelous article (old, but still valid today):
The Law of Leaky Abstractions.
When the concept of encapsulation was first introduced, it seemed like a sound idea. And indeed it is, but the problem with it begun when its original meaning was lost. Leo Brodie, in his wonderful book "Thinking Forth", explains the original concept quite well, in the section 'Hiding from whom?':
"Because modern mainstream languages give a slightly dierent meaning to the phrase 'information-hiding', we should clarify. From what, or whom are we hiding information? The newest traditional languages such as Modula 2 (can you imagine how old this book is? LOL!) bend over backwards to ensure that modules hide internal routines and data structures from other modules. The goal is to achieve module independence (a minimum coupling). The fear seems to be that modules strive to attack each other like alien antibodies. Or else, that evil bands of marauding modules are out to clobber the precious family data structures."
"This is not what we're concerned about. The purpose of hiding information, as we mean it, is simply to minimize the effects of a possible design change by localizing things that might change within each component."
It is especially noteworthy that Forth
is not an object-oriented language. So, how comes that languages that aren't even object-oriented got this better that the ones that tout 'reusability' as one of their strengths? The problem lies not in the OO languages themselves -most of them implement mechanisms to achieve the needed encapsulation-, but in how the entire concept of
object orientation was understood by the general public.
If one were to ask several people to explain the concept of object-orientation, most likely you'll end with widely differing views. One of the most common is:
"An object is a representative of a real-world entity, that has unique attributes called 'properties' that you can manipulate, and you can tell it to do stuff using commands called 'methods'"
Perhaps, when you first heard of this 'object-oriented paradigm', this was the first definition you came across. Sounds reasonable, right? Perhaps, but this definition leads to the 'everything is an object' kind of mentality (that languages like Java
enforce to you). But let's dissect the above statement, so we can see why this definition is fundamentally flawed.
First, objects need not be 'representatives of real-world entities'. Which real world entity a 'BankAccount' class represent? Or an 'AcyclicGraphNode' class? Or a 'LinkedListItem' class? None, they're abstract concepts that get wrapped (read:encapsulated) onto a class for convenience. They
may represent real world entities: a 'House' class, an 'Animal' class, or a 'Player' class, but need not to. How would you represent a mathematical function using a class? You don't, that's a concept that does not need encapsulation of any kind. Thus, the 'everything is an object' mentality is not a very good conceptual model to begin with, if only because it's very limited in its scope and does not allow for middle grounds.
So, you may ask, what is an object
to you, then? This is how I conceive objects:
"An object is a code entity that represents a concept of the underlying problem domain and exposes functionality to work towards solving that problem"