So where are we?
I've been trying to understand why the selection handling bothers me so much. I think it's based on the responsibilities of the classes: I want the planning game screen to be responsible for holding the buttons, the Background, and the summary. Currently, the planning game screen also tracks the selection because that's what the action listeners work with. But I think instead we should make the Background track all selections; some of the action listener work belongs there too. This change is a bit tentative, so I will certainly checkpoint my code so that I can return to it if I don't like where things end up. (I think of checkpointing as saving a version for easy recovery without releasing it to the whole team; this may or may not be easy in your environment.)
Updating the cost is done by any button press that might change it. Each command must be careful to include a call to updateCost() after any changes it causes. In the current code, this is done by putting the call in each listener. One way to reduce this duplication is to subclass listeners from a common parent and make the parent responsible for the call. An alternative would be to introduce listener-style notification; the summary would listen for changes in the underlying Background or velocity and would update itself accordingly . PropertyChangeEvent fits our needs. On Background, the two things we typically monitor are the count and the cost. Rather than be specific about which property has changed, I'll use the standard bean convention that null for a property change means anything might have changed. This change is a refactoring, but it's into the realm of large refactoring (or would be if this program were of a substantial size). I don't feel like my tests will adequately cover it, so I'll introduce new tests to make sure Background sends events. Since this is a relatively big change, checkpoint before you start.
The action listeners still have duplication: Several of them need to check whether there are any cards before they do their work. This suggests a change: Why not disable them unless they apply? This is a user interface change, but our user likes the idea.
Look back at Card. It still depends on Background. When a card is clicked, it looks at the background and tells the background to move that card to the front. This is an undesirable dependency because Background knows about Card, and Card knows about Background.
Now compare your code to the original. Does it communicate better? Is it simpler? Better structured? |