Over the years it has become apparent to me that the better you encapsulate, the less heart ache you'll have if you want to change all your APIs around. At the same time, it has also become clear that the better you encapsulate, the more APIs you are creating.
To explain this a little better, let's take an example:
aNode styles background color red
In this example, we start from aNode and we ask for styles for aNode, then we ask for the background of the styles, then we ask for the colour of the background and finally we ask for the red component of the colour. This is a classic example of a multipart send. This is an example that a pure encapsulator would point to say and say "This is brittle".
Yet at the same time, we know the code is readable and obvious as to what it's doing. It's clear what objects we're talking to, who's responsibility is what and things -are- well encapsulated.
If we were going to be encapsulation gods, we would make the following methods:
Node>>styleBackgroundColorRed
^self styles backgroundColorRed
Styles>>backgroundColorRed
^self background colorRed
Background>>colorRed
^self color red
It's quite clear that this cures encapsulation, sure, and if you want to get your backgroundColorRed from some other source, it's easy for a subclass to override the behaviour. However, now we have a mess.. in several respects. We've added three more methods to our code base that we have to maintain - and worse, we've added three new bits of API (whether you stick them in private categories or not!).
So there's clearly a trade off. When does encapsulation apply? .. when something isn't API? - certainly.. but where do you draw the line?