My school's CS program avoids any mention of object oriented programming, so I've been doing some reading on my own to supplement it -- specifically, Object Oriented Software Construction by Bertrand Meyer.

Meyer makes the point repeatedly that classes should hide as much information about their implementation as possible, which makes sense. In particular, he argues repeatedly that attributes (i.e., static, non-computed properties of classes) and routines (properties of classes that correspond to function/procedure calls) should be indistinguishable from each other. 

For example, if a class Person has the attribute age, he asserts that it should be impossible to tell, from the notation, whether Person.age corresponds internally to something like return current_year - self.birth_date or simply return self.age, where self.age has been defined as a constant attribute. This makes sense to me. However, he goes on to claim the following:


  The standard client documentation for a class, known as the short form of the class, will be devised so as not to reveal whether a given feature is an attribute or a function (in cases for which it could be either).


i.e., he claims that even the documentation for the class should avoid specifying whether or not a "getter" performs any computation.

This, I don't follow. Isn't the documentation the one place where it would be important to inform users of this distinction? If I were to design a database filled with Person objects, wouldn't it be important to know whether or not Person.age is an expensive call, so I could decide whether or not to implement some sort of cache for it? Have I misunderstood what he's saying, or is he just a particularly extreme example of OOP design philosophy?

I don't think Meyer's point is that you shouldn't tell the user when you have an expensive operation. If your function is going to hit the database, or make a request to a webserver, and spend several hours computing, other code is going to need to know that.

But the coder using your class doesn't need to know whether you've implemented:

return currentAge;


or:

return getCurrentYear() - yearBorn;


The performance characteristics between those two approaches is so minimal it shouldn't matter. The coder using your class really shouldn't care which you have. That's meyer's point.

But that's not always the case, for example, suppose you have a size method on a container. That could be implemented:

return size;


or

return end_pointer - start_pointer;


or it could be:

count = 0
for(Node * node = firstNode; node; node = node->next)
{
    count++
}
return count


The difference between the first two really shouldn't matter. But the last one could have serious performance ramifications. That's why the STL, for example, says that .size() is O(1). It doesn't document exactly how the size is calculated, but it does give me the performance characteristics.

So: document performance issues. Don't document implementation details. I don't care how std::sort sorts my stuff, as long as it does so properly and efficiently. Your class also shouldn't document how it calculates things, but if something has an unexpected performance profile, document that.
