From: Jeremy F. <jfi...@ma...> - 2002-11-06 01:00:46
|
Perhaps we can have it both ways -- build a "dumb" contentObject infrastructure that is used in various services, then create some = wrapper components that perform like "smart" components by encapsulating = common tasks one does with the dump contentObjects and the services. Hmm, = that might actually be quite nice and provide a nice gradual learning curve = for a developer (starting with the "smart" layer and then being able to = branch out into their own customized use of the "dumb" contentObjects with = services). It would also, I can see, make it easier to extend Modus by layering = on services instead of having to change baseContentObject. I guess I'm = sold on the general concept, though I want to make sure that building a simple = Modus app requires substantially less coding then building a "regular" CF = app (which is where this whole thing started). Yes, yes. That is kind of what Sean was getting at when he mentioned = syntactic sugar. You can have a wrapper or facade component that handles = all of the interaction with the "dumb" layers of the system. Sean had = actually mentioned a few UDFs, but I think another static CFC would be = the The persistence layer can be entirely separate from the = contentObject layer as well as a display layer because the glue that = ties the whole system together is the xml descriptor. That's really = where the "smartness" lies. All components have to be able to handle = this in a standard way since it is the object definition. So a service-based Modus might have the following components: Persister - this is responsible for moving data on and off disk. It = should maintain the memory-based cache as well. ContentObject - this essentially provides data validation services. = Anything else? Renderer - suited primarily to HTML for now. At the least this takes = over for renderBasicForm(). Facade - the sole instance that is created externally. It finds or = instantiates the appropriate components as defined in the descriptor. = Provides coarser-grained access to the dirty work of retrieving, = rendering, validating and storing a contentObject. This is where the = "substantially less coding" requirement is fulfilled. As you said Nathan, this leaves open lots of room to plug in more = services, such as security, locking for data integrity and whatever = else. And if done well, the only code that would need to change would be = the facade. As I've been working on the collections idea we hashed out last week it = seems that it would be more efficient for each object to provide its own = extension to the persister. An approach similar to this is shown in the = 4th chapter of Ben Forta's new J2EE book. They have EJBs for simple data = access/mutation, but use SQL wrapped in CFCs for complex queries. With = Modus we could put the complex queries in the contentObject's own = persister. For example, pressrealease_dao extends dbpersister with a = "getAllRelated()" method. This would provide a significant performance = boost for searches and sorts, particularly for the table-based = dbpersister I've been working on. But, it would also work for the = wddx-based persisters, maybe even using Xpath searches on the wddx = itself since CFMX supports that now. Much of this could probably even be = defined in the descriptor so that developers wouldn't need to worry = about the code for simple joins. Starting to sound like container = managed persistence, huh? In any case, I've got something like this = working in the forums app I started called getQueryByCategory, so it's = not too far fetched. I'll have to noodle on Jeremy's proposed API (and yes, I realize it = was meant as a proof of concept, not a finished product). =20 Yes, I haven't actually implemented anything, although I don't think it = would take much to make this work from the existing code base. The first = and most important step is going to be the xml descriptor. I still think we should maintain a development style that uses = methods, ie: honda.getField("color").setValue("blue") rather than just honda.color = =3D "blue" -- mostly to keep things consistent and because it just feels = tighter to me for some reason. Though, perhaps it's overly verbose. The last = big project I managed we used Turbine (from Apache) and it allowed you to = do honda.color, but under the sheets it turned that into honda.getColor() = -- that is, it was a short-hand way to access the method rather than = exposed data members. That might be tricky to provide method-based access since the persister = would probably work best if it returned a struct. For example: = honda.fields.color =3D "blue". In fact, the EJB example that I mentioned = does just this. They use a value object java bean to return a methodless = instance of the EJB and coldfusion treats it just like a struct. I hate = to see the methods go too, making the system feel less object-like, but = it seems to be the best solution for getting data in and out of static = components. -Jeremy |