|
From: Nathan D. <na...@ch...> - 2002-11-16 01:57:31
|
Jeremy:
You're clearly doing a fair amount of work. Sorry I've not been keeping up
with it as much as I should.
A couple questions that came to mind immediately:
1) I'm not totally clear about the render objects. What would a pdfrenderer
look like, for instance? Would it be a generic way to make contentObjects
render in PDF?
2) We may have to just agree to disagree about the need to have different
aliases (i.e.: "pressRelease1" and "pressRelease2") to describe the same
descriptor and the need to have the same alias (i.e.: "pressRelease") to
describe different descriptors (i.e.: "org.bacfug.pr" and
"com.macromedia.pr"). That is, my personal style would be to decouple
contentObjects, their descriptors, persisters, descriptors, etc. from an
"Application." Which is not to say that Modus might not want to build out
some kind of application-level abstractions, but I'm just not sure why those
need to relate directly to the contentObject layers.
In general, I guess that I'd prefer a less verbose config file and have to
just type out "com.mydomain.stuff.thing" instead of being able to type just
"thing" because I have all that config data. Strikes me as somewhat opaque,
or something like that -- but, maybe I'm insane that way ;)
I guess it seems that rather than having a config file that tells me
pressRelease2 is a pressRelease that uses remoting, I'd rather have some way
to have a remotingPressRelease and tell it that it should use the
pressReleaseDescriptor.
3) I also must admit to feeling like I'm starting to get in over my head as
far as the design patterns you are employing. I'm not yet under water, but
it seems to be going there. I haven't put the time in necessary to fully
grok the last two chunks of code you posted, but my fear is over abstracting
in places that won't be useful to the 90%+ of CF folks who won't be able to
quickly embrace the various levels that the components are introducing. I'm
not saying it's yet there, but given the skills the rest of you have I'll be
happy to represent the "dummy" crowd ;)
Part of it is that I thought of some of the steps I was taking initially as
akin to "denormalizing" a database schema for performance. Except in my
case it was "deabstracting" certain things to make life easier. I guess an
example of this would be that a com.changemedia.pressRelease had one and
only one persister -- to me, the process of having to define my raw data
storage separately from the way I might persist it or manipulate it seemed
like overhead I was doing away with. I was OK with it partially because I
could always say otherKindOfPressRelease extends pressRelease and just
changes the persister it uses -- I was imbuing the contentObject descriptor
(which was CFPROPERTY and is now moving to XML) with more meaning than just
being akin to a DDL in a database. Yes, this violates many pure design
abstractions, but for most of the apps I've ever seen built it would save a
lot of time and energy that would be better spent on higher order
functionality. I'm not saying we shouldn't do the "service model", and I
really like where you are going with modus components (though, perhaps those
should be called something like "plugins" to avoid confusion with CF
components) because that is much more easily extended than where I was going
with the monolithic baseContentObject. I also don't want to discourage the
excellent work and thinking that you're doing (and I'm not!!!).
4) Can you help me understand how you are using:
defaultPathToDescriptors="C:\CFusionMX\wwwroot\modustest\descriptors"
pathToModus="C:\CFusionMX\wwwroot\org\bacfug\modus"
In looking at your code, I see use of things like "org.bacfug.modus...." --
how would this reconcile if pathToModus did not live off the web root?
I'd also be happy to do away with the need to have each "application" define
where it's descriptors are and have that be part of the call to a Modus
initializing script included in Application.cfm (or in some other way
globally). Or, to just have a developer be explicit about where descriptors
are as they config their application. BTW, I am not saying I'm against
Application.cfm, only that if possible I'd prefer to not require
CFAPPLICATION or to use application variables by default. The short answer
to this is that I have been making my applications with CFAPPLICATION since
the CFLOCK issues cropped up -- global vars went into request vars and I
went back to using serialized sessions out of the database (which had the
added benefit of making my applications very easily clusterable). In MX I'm
less concerned about application scoped variables and CFAPPLICATION in
general, but it feels like an encumbrance more than a liberator. Perhaps
there is a deeper discussion to have about the role of Modus and the nature
of a Modus contentObject, though. Perhaps a compromise here would be to
have the global modus config file have a notion of "profiles", each of which
can have different defaults (and there would be a default profile). I could
then tell a descriptor (or a facade, perhaps) which profile to use. That
would get you the config level short-cuts and prevent the need for
CFAPPLICATION and application-specific configuration of Modus (and has the
benefit of being able to use a single profile in multiple applications, and
for third-parties to build out profiles and ship them as a fairly tight
addition to an existing Modus installation).
We might then have something like:
<profiles>
<profile name="bacfug">
<components>
<persister type="org.bacfug.modus.persistence.fileSystemSerialized"/>
</components>
</profile>
<defaultProfile>
<components>
<facade type="org.bacfug.modus.facades.webfacade"/>
<validator type="org.bacfug.modus.validation.validator"/>
<renderer type="org.bacfug.modus.rendering.baserenderer"/>
<persister type="org.bacfug.modus.persistence.simpleobjectinstance"/>
</components>
</defaultProfile>
</profiles>
Where the defaultProfile sets all defaults and each profile can then
override one or more of them (and possibly add new ones). Though,
personally, I think it would be sufficient to just define defaults for all
components, then let a developer override those in the proper place (facade
or descriptor, depending on how things shake out).
5) I do think that having the ability to "extend" a descriptor is fairly
critical, but I can see how that will be relatively straight-forward in your
setup.
6) I agree we shouldn't get hung up on modus.get() vs. server.modus.get() --
though, I do think it's worth having a convention. My preference is
server.modus.... for basically everything as the "standard" way to code in
Modus.
OK, gotta run . . .
- n
|