skiphoppy
skiphoppy

Reputation: 103031

Model shared between two objects

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

Answers (3)

Azder
Azder

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

George Armhold
George Armhold

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

Sam Barnum
Sam Barnum

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

Related Questions