This is a CSci 53 lab from 2008. Look at the "Ball World" and the "Class Extension" chapters.
Let's analyze the code that was developed for that lab. First of all look at Ball.java.
Notice first of all that
public class Ball implements CanBeTold
CanBeTold is, almost exactly, the same as java.util.Observer. Later in this lab we will critique Java's implementation of the Observer design pattern. For now, let me just say that since the lab was intended for an introductory Java class, I did not want to expose the students to the awkwardness of Java's Observable class. (In this lab you will meet that awkwardness soon enough!)
I renamed java.util.Observer's update() method and called it respond() and also avoided the two parameters that Java's method require.
Instead of the class java.util.Observable I use the public class Manager. Methods are replaced
java.util.Observer
Manager
addObserver(Observer o)
register(CanBeTold o)
deleteObservers()
clear()
notifyObservers()
tellAll()
Returning to the Ball.java class, we note some features:
If you intend that ball objects should be subject to manipulation from outside -- perhaps by gravitational or other forces, then perhaps you should provide getters and setters for all attributes from the get-go.
Simulations need to be lifelike but not TOO lifelike. That point we just made about real balls not aware of the boundaries where they will bounce. If not the ball object then who will know when a bounce is needed? You could, I suppose, have a "Physics" object that would keep an eye on everything that is happening and when an event occurs that changes an object's motion then the Physics object would ensure the update happened.
I prefer the alternate view that a realistic simulation can occur by endowing ball objects with functionality that enables them to discover when their motion would take them out of bounds and then to correct before they are displayed out of bounds. This localizes the physics and makes for simpler programming. This is not to say that there is not a place for another kind of simulation that remains truer to physical laws.
I mentioned two paragraphs ago that it might be a good idea to provide the Ball class with getters and setters for all its attributes. If you do this then the bouncing could be managed by the Canvas in which the balls are bouncing. The Canvas would need a data structure containing references to all the live balls and constantly monitor each ball's position to know if it needed to bounce. Then the Canvas object could use the getters and setters in the ball to make the bounce happen.
On the other hand it's possible that it's what you need for your particular application. We should be open to all kinds of design options and choose what's better on the basis of our understanding of the costs and rewards.