|
From: Jeremy F. <jfi...@ma...> - 2002-11-05 20:30:31
|
A few thoughts that might add to the discussion as I try to make sense =
of Sean's proposal in light of Modus' current architecture:
My suggested approach - making persistence a *service* - allows you to =
side-step this. I can easily make my car object persistable by =
creating=20
an XML descriptor for it (externally) and then binding it into the=20
persistence system dynamically. Sure, it means you can't save=20
honda.save() and instead you need to create a carPersister (binding in =
the car XML descriptor) and then say carPersister.save(honda) but that =
isn't really a big hardship - yet it buys a lot of flexibility AND it=20
removes the per-instance overhead of the persistence mechanism=20
(methods, metadata, inheritance).
So if I'm reading this correctly, you would do a one time call like:
<cfif NOT isDefined('server.carDescriptor')>
<cffile action=3D"READ" file=3D"car.xml" variable=3D"carxml">
<cfscript>
carDescriptor =3D xmlParse(carxml);
server.carPersister =3D =
createObject("component","modus.simpleobjectinstance");
server.carPersister.init(carDescriptor);
</cfscript>
</cfif>
carPersister would return a structure of data, not an object instance. =
All of the work that contentObject had done to instantiate an object =
would be taken over by the persister. It would simply populate a =
structure according to the xml descriptor, rather than inheriting from =
basecontentobject, working through the metadata and instantiating =
individual fields to hold data. The persister might be used like so:
myCar =3D server.carPersister.get(carID);
myCar.tires =3D 4;
myCar.color =3D "blue";
server.carPersister.save(myCar);
If CF had real interfaces, I wouldn't be as worried about this from a=20
design point of view. If CF was higher-performance in its OO support, =
I=20
might also concede this point on the grounds of simplicity. But =
neither=20
of those are true so I'm going to stick to the idea of=20
persistence-as-service (and would push for presentation-as-service =
too).
and I think Sean is even suggesting that the contentObject be made a =
static or service-oriented component as well, doing such things as data =
validation. For example:
<cfif NOT isDefined('server.car')>
<cffile action=3D"READ" file=3D"car.xml" variable=3D"carxml">
<cfscript>
car =3D xmlParse(carxml);
server.car =3D =
createObject("component","modustest.contentobjects.car");
server.car.init(carDescriptor);
</cfscript>
</cfif>
and then car and carPersister could be used together like:
myCar =3D server.carPersister.get(carID);
myCar.tires =3D 4;
myCar.color =3D "blue";
myCar =3D server.car.validate(myCar);
if (NOT myCar.hasErrors){
server.carPersister.save(myCar);
}
Besides, a plugin-based architecture like that is very flexible and is =
well-enough documented in the literature that developers shouldn't =
find=20
it too alien (note that Fusebox MX uses a plugin architecture, much to =
my surprise - and delight!).
The form generator could be just another plug-in that reads the xml, =
receives an object-as-struct from the data store and returns the html. =
Incidentally, I worked on a form generator cfc this summer that does =
just this: accepts an xml object, constructs the html (with stylesheet =
support) and return the form as a string. Even for complicated forms =
with multiple select lists and such it never took more the 40ms to do =
its work.
As Sean said, we'd be losing the content object 'as object' in favor of =
more flexibility and greater performance. Sure the data is all exposed =
as a structure, rather than kept nice and tidy behind accessor/mutator =
methods, but CF doesn't seem to be ready to handle the full OO shebang.=20
Just thinking out loud here. What do you think?
-Jeremy |