Using OO Observer pattern without updating object

2019-06-05 03:34发布

问题:

I'm building an application which contains a GUI and a Model. I'm using the Observer pattern (using java's built in interfaces) to update the GUI when fields in the model are changed.

This is generally working fine, but I have a situation in which a particular String variable in the model (specifically the url of a file) can be changed by two separate JTextFields (swing) the contents of which actually reflects the value of the model variable in question.

The issue I am having comes from the fact that an change in one of these JTextFields needs to cause an update to the state of the model, and the contents of the other JTextField. My Model ensures that notifications are sent to observers only in the case that the state of the model has changed. However, the process by which JTextFields are modified involves blanking it's text content then reseting it.

Without going into too much detail, the upshot of this is that the update / notification process gets stuck in an infinte loop. I have temporarily hacked around this by setting aside the observer pattern for this particular problem, but I was wondering if anyone could suggest a neat way of ensuring that a particular component is not "updated" by a change which originated from the same component.

Any help appreciated.

回答1:

As discussed in Java SE Application Design With MVC, this is one of several Issues With Application Design. The suggested approach relies on a PropertyChangeListener, illustrated here. The PropertyChangeEvent includes both old & new values for reference.



回答2:

This link which talks about a Bidirectional Observer may offer some help on this.

It does seem in your case that the Model and View are trying to update each other. The solution would lie in enforcing the direction of an update. For example Inner layer -> Model -> View and View -> Model -> Inner layer. So it wouldn't really be a true Observer Pattern.

The update(Observable o, Object arg) method of java.util.Observer does accept an Observable(Subject) object. This object can be used to provide a hint to the Model asking it to propagate the update inward rather than toward the View.

I gave it a quick try and found that setting up Bidirectional observer (using Java apis) is not as simple as I thought. But you could venture a try.