William Cook talks about the difference between objects and Abstract Data Types (ADTs) in this great paper: On Understanding Data Abstraction, Revisited. In his treatise on objects, he lists a property called “Autognosis” which, in his words, describes the contraint:
An object can only access other objects through their public interfaces.
Put another way (again by Cook):
An autognostic object can only have detailed knowledge of itself.
I find this constraint particularly interesting, because it’s something that’s easily violated in conventional OOP languages. Presumably because it’s so easy, a lot of OOP code also actually does violate it.
So what’s the problem? Well, to compute the sum of the two vectors the augend needs access to the private data of addend (addend._x and addend._y). Thus, one object (the augend) accesses another object (the addend) through something else than the public interface. This violates the Autognosis constraint.
By itself, this doesn’t bring us very much, we’ve just wrapped the instance variables. However, from an extensibility point of view this has brought us a great lot: we can now create new, interoperable vector implementations:
And their interoperation:
Let’s take a moment to appreciate what we did here. We were able to introduce a new vector implementation and use that seamlessly within our existing code, without needing to change any of that existing code. This is great, since it means that your application can be extended and improved after writing it in the first place, without needing to modify it.
There is another great advantage to this: besides you writing new extensions, other people can do that as well, allowing your application to do stuff that you never imagined in the first place. Arguably, the vector example doesn’t really show those traits, but OO design principles is exactly what’s at the heart of platform ecosystems such as iOS and Android Apps, or even the internet itself.
To summarize, that’s one of the great benefits of OOP: objects provide for autonomous extensibility with interoperability. Autognosis is one of the key facilitators of that property.
Also notice that nowhere in this post I either talked about classes or inheritance, yet still arrived at some very useful properties directly related to OOP. This strengthens my beliefs that classes and inheritance are not fundamental parts of OOP.
I haven’t said too much about ADTs in this post, however I’ll try and do a follow up post to explore how you’d do a similar extension using ADTs.
Inspiration for this post came from: