Reputation: 103031
I have three classes interacting in an interesting way. One is a model class, and it has to be accessed by both of the other classes, so a single instance of it is kept as a member of each. Both of these classes interact with the model in different ways.
There are a couple of instances where the model object has to be completely thrown away and replaced with a new instance, and this complicates things. And these occasions arise in both of the viewing/controlling classes. So, either one of those classes has to be able to send a signal to the other saying "We need to coordinate and facilitate the replacement of our Model object with a new Model object." Right now I have code in class B to tell class A to construct a new Model and send it back, but now I need to handle the opposite situation, where the event arises in class A, and unfortunately class A does not have a reference to class B and probably shouldn't.
What's a good way to handle this?
Update: Sorry, folks, this can't be a singleton. Singletons are when you need to guarantee there's only one of something. That has nothing to do with any of the requirements I expressed above. This class is not a singleton and shouldn't be.
Update: Up till now, there has actually only been one instance of this Model class, but I had a vague suspicion I needed to allow for more, and I didn't want to limit myself by using the Singleton design pattern when that actually addresses different concerns from what I have. Turns out I was right: yesterday I received a new requirement and now I need support an arbitrary number of these. :) Don't limit yourself when you don't have to, and don't misuse design patterns for situations where they were not intended!
Upvotes: 2
Views: 297
Reputation: 4728
Ok, if you need to change the model (but not force) you can make a listener interface, and make both objects A and B implement it:
public interface ModelListener {
public void modelChanged(Model newModel);
}
and at the proper time you can notify the listeners of the new model change. You can also have a list that holds all the registered listeners.
List<ModelListener> modelListeners = new ArrayList<ModelListener>();
public void setNewModel(Model m) {
for (ModelListener aListener : m.modelListeners)
aListener.modelChanged(m);
}
As always there are tradeoffs between simplicity and robustness. You might want to experiment with the levels you need for your own case.
Upvotes: 1
Reputation: 31104
I encounter this design issue often in GUI projects (Swing, GWT). What I usually do is create a higher-level "State" model, which holds an instance of the object that is shared between 2 or more classes. State then has a ModelListener interface, which the other classes can implement to get notification of changes to the underlying model. State.setFoo() then fires ModelChanged events to the listeners, which respond accordingly.
Upvotes: 0
Reputation: 10744
You'll want an intermediary model layer, a model "holder" object that each of the two classes reference. The ModelHolder holds a reference to the model.
This ModelHolder should also support listeners, so when its model is thrown out, it can notify any listeners that the model has changed.
Upvotes: 5