Re: [Figleaf-developer] No need for proxies - at least at the moment
Status: Alpha
Brought to you by:
steckman
|
From: Greg S. <ste...@on...> - 2004-07-02 16:18:32
|
sam...@ma... wrote: >I had a major brainwave last night and realised we don't need proxies at all. >Here is my new proposed workflow for introducing developer-defined beans into >the system. > >1. The ProxyFactory (now needs to be renamed) gets given an object >2. It invokes an ObjectIntrospector to retrieve an Informative implementation >3. It creates an implementation of the new interface Bean (needs a rename?) >which implements Informative and Observable. In addition it defines two new methods: > >Object getProperty(String propertyName); > >void setProperty(String propertyName, Object propertyValue); > >These methods fire change events accordingly without any need for proxied method >interception. > >4. This is returned to the UI layer (or whatever). > The object returned must be an "instanceof" the object I wanted. Would this do that? > >5. To interact with this developer defined object, the UI first gets a list of >properties to expose them (which comes from the underlying Informative >implementation). To invoke a method, it calls getProperty() or setProperty() >with the relevent property name. > >This removes the need for all proxies, results in easier to test, less >complicaed code, and I think gives the UI evervything it needs. We may still >need proxies for remoting/securirty/validation or whatever, but for the moment >it doesn't look like we need to. > How does the UI then access non-property methods of the object? The object needs to be able to expose to the UI actions that can be invoked by the user. That is the main purpose of the MethodDescriptors. > >Changes to support this: > >* The ProxyFactory/CglibProxyFactory will become a BeanFactory/BeanFactoryImpl. >The existing getProxy becomes makeBean > >* Property becomes your PropertyDescriptor > >* Mutable becomes Observable > >So now you can call: > > Bean bean = beanFactory.makeBean(developerDefinedObject); > ... > bean.getProperties(); > bean.getName(); > bean.getDescription(); > ... > bean.addChangeListener(); > bean.removeChangeListener(); > ... > Object retVal = bean.getProperty(propertyName); > bean.setProperty(propertyName, newValue); > >Further down the line getProperty and setProperty can throw validation >exceptions, or we can add an isValidPropertyValue() method or something. > >What do you think? > >sam > > > > Currently there are interfaces defined which allow the following: Informative myInformative=theObjectManager.newInstance(com.foo.bar.class); PropertyDescriptors[] pd=myInformative.getClassDescriptor().getPropertyDescriptors(); MethodDescriptors[] md=myInformative.getClassDescriptor().getMethodDescriptors(); myInformative.getClassDesctiptor().getDisplayName(); myInformative.getClassDesctiptor().getDescription(); etc. I think this essentially is the same as what you are proposing. All the "magic" happens in the ObjectManager.newInstance call (and other methods that return Informatives). But the following constraints should be maintained: myInformative instanceof Informative evaluates to true myInformative instanceof com.foo.bar evaluates to true The array of PropertyDescriptors is not a problem (at least for a UI generator) because it will add them all to the UI (in the order as returned by the object). There is no need for the UI code to invoke a property by name. It maintains references to the PropertyDescriptor and then just invokes the readMethod or writeMethod when required. I almost have a whole slice working with objects that implement Informative on their own. The only missing piece would be to implement an Introspector that knows how to make a proxy that implements Informative given an object instance that does not. Greg |