Here's a switch. Since Blaine Buxton quoted me from a comp.lang.smalltalk posting, I thought it would be appropriate to post my article here. As a result, I'm referencing Blaine posting my own quote.
The question was whether getter and setter methods were indicative of bad design. Some people have rules like "don't write getter and setter methods". Here are my thoughts:
Rules like "don't write getter and setter methods" are off the mark. The problem is not getters and setters. The problem is coupling and distribution of knowledge. The fear is that if you have getters and setters on an object, then other objects are going to extract the private data of the object, do some processing on it and write it back. This operation increases the coupling between the two objects and leads to a poorer design.
When it comes right down to it, there is basically one problem that object oriented programming tries to solve: rigidity. Rigidity occurs when a small change in the design requires significant changes to the code. For example, if you decide to rename an instance variable, any method that uses that instance variable needs to be modified. If you need to add a parameter to a method, any other method that calls it needs to be modified in order to pass in an extra parameter.
What we want is what I call "Local Change, Local Effect". This means that a change in one area only affects a small amount of code in that area and doesn't cause massive changes and propagation of changes.
Back to getters and setters. The getters and setters on their own aren't a problem. It's how and why they are called that can cause problems. If other objects are calling getters and setters then doing work on the result, it's likely that many objects need to do the same work. This results in duplicated code. Duplicated code causes rigidity. Any design change that affects this code will affect all copies requiring changes to be made across the system. It's better to have one copy of the code performing this operation and the natural place to put that code is in the original object.
Having said that, there are many cases where instance variables of an object are fundamental to the object's behavior and you need to be able to set them or get them. Just have a look at why you are getting or setting the variable. If it leads to duplicated code or distribution of knowledge, you are introducing more rigidity.
BTW, I wrote a physics simulator myself (in Smalltalk) and found that the best algorithm to solve the physics equations was to extract the positions and velocities from the particles, store them into one big vector, run Adaptive Runge Kutta on the vector, then write all the data back. Although this sounds bad, it didn't really break encapsulation because the objects themselves handled the extraction of the data and the restoring of the data after the ARK algorithm ran. The ARK algorithm just considered it a big vector of arbitrary variables that needed to be manipulated and didn't care what the values were for and what objects they belonged to. Code for this physics is in the Cincom public store repository (for VisualWorks) and in SqueakMap (for Squeak).