It's well-known that computer algorithms (and thus programs) consist of two elements: data, and functionality (operations on said data). Different programming models offer different ways to look at the interaction between these two elements.
Object-Orientation is probably the newest and most popular model in that regard (and it's pretty old), and it says the following:
- Data and functionality are tightly coupled.
- Data is more important.
This makes sense. Functionality is meaningless without data to work with (data exists even without manipulation, it's just kinda boring), and it's also meaningless without the correct kind of data. So the solution is to put data inside what they call "objects" (I feel a bit like Dr. Evil with these quotes) and surround it with methods to act upon that specific data.
While this makes sense, it also misses an opportunity: Functionality doesn't have to work on specific data; it can work on a class of data (and I don't mean OO-class, I mean kind of data). This is proven true by functional-programming styles all the time: A tuple of 3 integers can represent a color (RGB), or a position (xyz), and a length function can be useful for both cases.
This example can be imitated in OO, if both the Color class and Position class inherit from class Vector3. However, it is not considered good practice in OO to inherit by data rather than by nature. This can be easily seen in Java's awt's definition of Color: it inherits from Object, and implements no vector behaviour. Well it can't inherit from vector, because it has more data than just RGB, and it needs Object's functionality. So if we want to measure the intensity of the color ("length"), we have to write a function especially for Color, which is functionally equal to length. Not pretty!
I hope the idea behind the separation of data and functionality is beginning to become clear. Data exists even without being manipulated, and should be class-able without being dependant on manipulations. In order words, It sometimes makes sense to manipulate data by what it is, and not what it is supposed to be.
The problem I presented, can be solved by a relatively new design mechanism: protocol, or contract. It's a bit like interfaces, but better. Contracts allow to specify functionality without inheritance. By giving each data-class its own contract (at least conceptually), you can design some separation of data and functionality.
But this alone is a bit of a hack. True separation goes much further. For example, did you know that in python, converting a list to a tuple is O(n) ? There is no reason for this to happen, and if there was any separation of data and functionality, it would be O(1).
I have a lot more to say about this subject, but I think I'm done for now. I hope this text wasn't too confused or vague; I was figuring it out as I was writing, and it might reflect.
So, to conclude:
- Data and functionality are not tightly coupled.
- Data-class and functionality are tightly coupled.
- Data is more important.