I have an interface FooModel
and a class DefaultFooModel
that have a few simple properties. I am getting stuck on a boolean enable
property because I want to have this be vetoable/deferred:
public interface FooModel {
public boolean isEnabled();
/** returns old value */
public boolean setEnable(boolean enable);
public void addFooListener(FooModel.Listener listener);
public void removeFooListener(FooModel.Listener listener);
public interface Listener {
public void onFooEnableUpdate(boolean newEnable, boolean oldEnable);
}
}
What I want is for the model M to be the central point of access for the enable
property. But here's the sequence of events that I want to occur:
- view V (or any user of the model M) calls
FooModel.setEnable(enable)
on an arbitrary thread. FooModel may either:
a. immediately call
onFooEnableUpdate(newEnable, oldEnable)
on each of its listeners in arbitrary orderb. start a potentially long sequence of events whereby another entity (e.g. controller C) can decide whether to enable, and somehow let FooModel know, whereby the
enable
property may be updated and then we proceed as usual in (a) above.
The thing is, I'm not sure how to go about doing this.
Approach 1: the mechanism to do this shouldn't be part of the model's interface. Instead, my DefaultFooModel has an implementation which accepts a FooController
:
public interface FooController {
pu开发者_JAVA技巧blic void onFooEnableRequest(boolean newEnable, boolean oldEnable);
}
When DefaultFooModel.setEnable()
is called, it then calls FooController.onFooEnableRequest()
. The controller is expected to return immediately, but can take its time to digest the request, and then later call DefaultFooModel.updateEnable()
which causes the real onFooEnableUpdate()
to get called.
Approach 2: build something into the FooModel interface, but I'm not sure what.
Approach 3: Don't build anything into FooModel, just have it handle a regular property. Instead have the Controller listen to FooModel.onFooEnableUpdate() and override setEnable right away to the old value, then call FooModel.setEnable() later to set the new value.
Any advice?
Make FooModel a class instead of an interface.
The problem I see with making FooModel an interface is the complex logic that needs to be coded into the listener mechanism. It's generally not a good idea to force anyone who implements the interface to have to implement the listener logic as well.
Instead, make FooModel a class, implement the listener interface yourself, and creatively create public methods that can be overridden where you need to implement more specific functionality.
notifyListeners(boolean newEnable, boolean oldEnable)
notifies all listeners, by default by calling the following method, but could be overridden to do nothing, or to notify conditionallynotifyListener(Listener listener, boolean newEnable, boolean oldEnable)
notifies a specific listener
精彩评论