先看proxy, proxy本身是IFunction, 内有真正的IFunction - delegate, 以及IConfigurationElement element和一个状态变量。
private static class FunctionProxy implements IFunction {
// The "real" implementation of the function.
private IFunction delegate = null;
// The configured state of the extension element representing this arithmetic function.
private IConfigurationElement element;
// Whether this function has been invoked before.
// Used for lazy evaluation of the service.
private boolean invoked = false;
proxy的构造函数就是将element初始化,而delegate留作真正需要的时候再初始化,这里就是调用compute的时候
public FunctionProxy(IConfigurationElement element) {
this.element = element;
} //构造函数, 用plug-in.xml里面的xml element作为参数,初始化proxy类对象的参数this.element,这个参数会在后面getDelegate() 用到,用来初始化真正的callback class object。
public final long compute(long x) throws ArithmeticException {
try {
getDelegate(); // 这里,如果没有delegate, 则创建一个, 具体办法见下面
}
catch (Exception ex) {
throw new ArithmeticException("invalid function");
}
if (delegate == null) {
throw new ArithmeticException("invalid function");
}
return delegate.compute(x);
}
private final IFunction getDelegate() throws Exception {
if (invoked) {
return delegate;
}
invoked = true;
try {
Object callback = element.createExecutableExtension(CLASS_ATTRIBUTE); //这个element就是上面提到的,从配置文件传进来,首先初始化proxy类对象成员element,然后proxy类对象的element在真正实例化对象的时候,调用它来完成真正的实例化。
if (!(callback instanceof IFunction)) {
String message =
"callback class '"
+ callback.getClass().getName()
+ "' is not an IFunction";
System.err.println(message);
throw new ClassCastException(message);
}
delegate = (IFunction)callback;
}
return delegate;
}
}
proxy本身,要先于真正的delegate被建立。ProcessServiceMembers.process(), 在初始化每个IConfigurationElement的时候,new GridRow时候,都用新建立的function proxy去初始化GridRow。这样,6个GriRow建立了6个function proxy。但是此时,function proxy并没有真正的delegate,因为没有真正需要用到compute的功能,delegate是不会被建立起来的。
点击任意一个button, 触发compute的动作,比如,点击Echo,则GridRow::handleButton()里面会调用,function.compute(x), 这里的function是用function proxy初始化的。在functionProxy的compute()函数里面,会首先getDelegate(), 这个函数在没有delegate的时候,(比如现在),会通过以下方式初始化callback object。这就是lazy initialization的意思了。
Object callback = element.createExecutableExtension(CLASS_ATTRIBUTE);
delegate = (IFunction)callback;