|
Kurt – I’ve read this and need to digest it. I
think I understand the issues of the Iterator a bit more. Something that jump out are the point
about the “record” convention (is it a convention or is it just part of the API?)
in Reactor. I doubt that you’re going to have much consistency between
different ORM frameworks in their approach to problem solving. This means that
another ORM framework would probably have it’s own API and it’s own set of
issues. Have you considered abstracting out the
ORM framework? Perhaps you could have an ORM adaptor that “knows” how to work
with the ORM framework in question and can intelligently translate it’s API to
your needs? You can code against that interface knowing that if your ORM
framework of choice changes that you could simply create another adaptor for
the new framework. (thinking out loud here) Let me also say this: I’m listening. I
might not agree. I might not do what you suggest. But, I am listening. Your
points about having everything behind your services layer makes sense (and is a
better approach than I tend to follow). If nothing else, I’m taking your input
seriously. Doug From:
[EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Kurt Wiersma Just to clarify it isn't that we aren't going to use the iterator it is
just in our applications we will be abstracting them as much as possible so we
don't depend on Reactor specific API calls outside our service layer. Our
business objects (Reactor record objects) are used in our service layer, our
controllers, and then briefly in our views. So I am always very careful when designing
the API for our business objects because I know to change them will require
changes to lots of code. Persistence code should be abstracted so that the
other layers don't have to worry it and persistence frameworks can be swapped
out without causing the whole application to need to be changed.
On 3/22/06, Doug
Hughes < [EMAIL PROTECTED]>
wrote: I've been thinking about this and, to be brief, I'm not
convinced by your arguments about the naming of the getXyzRecord methods or the
Iterator methods. Of course, you could use the framework without either,
but you'd loose a lot of the real power. Furthermore, I don't see why
you're concerned about the implementation details of your persistence framework
when you're not about, for example, Mach-II. With Mach-II you have
certain interfaces you need to code against and certain framework-specific
conventions. I don't see the difference. Can you make any more persuasive arguments as to why the
getXyzRecord method should be renamed? It sounds to me like these two arguments really come down to
things you can get around by customizing the generated objects, though I don't
see why you would. With regards to OO Queries, have you tried them within the
past few days? Last week Sean set the query objects to be pooled.
His implementation made the pool, more or less, optional. Within the past
few days I made this the default behavior and, if I can be trusted as an
objective judge, I think it's markedly faster. (Note: simply running one
query won't show the improvement. You'll get the best results running
them in an application under load.) Doug From: [EMAIL PROTECTED]
[mailto:
[EMAIL PROTECTED]] On Behalf Of Shannon
Jackson Hello
everyone, Over the
last month, we have been building a prototype application-skeleton using
Reactor in conjunction with Mach-II, & Coldspring and have made lots of
interesting discoveries. I would like to share these with the list to
both praise Doug and the contributors for the amazing advancement in the area
of Coldfusion persistence as well as raise a couple of concerns for debate to
the great minds here. To begin,
it is important to understand that we build very large applications and have
been using Mach-II and Coldspring to reinforce an application architecture that
promotes reusability, scalability, & extensibility. Most of our
applications we would consider "enterprise applications" and the
following ideas are based in that context. The applications typically
consist of a service layer (managed by Coldspring) from which Mach-II
listeners, Flash Remoting, and Web Services interact with. The service
"beans" delegate tasks to an underlying CFC library consisting of
component packages that deal with specific business objects. These
business object "beans" are generated initially by a CRUDGEN
application that is tuned for our development pattern; after the initial
objects are generated (business object beans, gateways, DAOs, Listeners, and
service beans) we add the custom code that brings the components together. Reactor
presented itself as a fantastic way to remove the "generate once"
approach and database dependencies, as well as, a further reduction in labor
costs. Initially we were hesitant to pursue a prototype because of the
lack of table aliasing; however, Doug graciously added that and a few other key
features recently. These additions tipped the scales here and were enough
to convince management to allow time for a prototype. We took
our standard pattern and inserted Reactor under-the-hood. Very carefully,
we worked our way through each layer and evaluated the potential influences
Reactor would have on future applications as well as those we have already
created (retrofitting). After roughly three weeks of discussion, testing,
and tweaking we have come to a very pleasing discovery… Reactor only had three
issues that raised concerns across the department; all three technically could
be avoided by customizing Record objects—but one we feel needs to be addressed
because it is fundamental to application patterns in general. To start,
let's talk about the one critical issue. Using Reactor forces a naming
convention on embedded Record objects within the application.
Instantiating a Record object allows you to use your own naming convention
(i.e. – myBusinessObject = reactorFactory.getRecord('myBusinessObject')) and
that is great; however, if "myBusinessObject" has a hasOne relationship
to "myRelatedObject", no matter what you alias your
"myRelatedObject" in the configuration file it will force you to call
that object like this: myBusinessObject.getMyRelatedObjectRecord(). Ok, so
what is the big deal? Well, essentially when we evaluate frameworks we
look for anything that requires us to use techniques that are specific to that
framework (dependencies) that might interfere with potential replacements in
the future –or those that require lots of retrofitting. When it comes to
beans, it is important that we can call them what we want and use those names
to call embedded objects. We feel that beans should not be
"typed" by a naming convention anyways because it should not matter
to the application what goes on inside of the bean as long as it does what it
is supposed to. So, for the previous example, to remove the
Reactor-related naming dependency it would be
myBusinessObject.getMyRelatedObject()—notice that "Record" is not
there. This is how all of our existing applications look. One could
argue that we could customize the Record object to have a getMyRelatedObject()
method that calls the getMyRelatedObjectRecord() method but it is common enough
principle that I would like to request a dialogue about it. The remaining
two items—we have no argument that is valid as to why we can't work around
them, and they are: the iterator, and the query API. The Query
API, as we all know, is a little slow and that is the only beef we had with
it. If the performance were better it would be an outstanding syntax to
use for CRUDGEN in that it is much easier to build Query API statements as
opposed to the raw SQL. We will simply choose not to use that API yet
(but will likely auto generate the commented out code for future use). As
for the iterator, it simply creates to strong of a dependency above the service
layer for us therefore we will opt to not use it; rather, we will direct our
query requests to the service layer and have it get them from gateways. So,
all-in-all Reactor slips right into our application pattern relatively
painlessly. For those who choose to use the iterator in layered
applications, they should be aware that it does bind them to the Reactor
framework, or at the very least, requires them to replace it should they
migrate to another persistence framework in the future. With that
being said, Reactor rocks (bravo Doug) and we would like to hear feedback
regarding the myBusinessObject.getMyRelatedObjectRecord() naming issue.
One idea we have is that the framework provide a clean named method in addition
to the "Record" appended method if people are already using Reactor
in production. Sincerely, Shannon
Jackson -- Reactor for ColdFusion Mailing List -- [email protected] -- Archives at http://www.mail-archive.com/reactor%40doughughes.net/ -- Reactor for ColdFusion Mailing List -- [email protected] -- Archives at http://www.mail-archive.com/reactor%40doughughes.net/
|
- [Reactor For CF] Reactor R&D Shannon Jackson
- RE: [Reactor For CF] Reactor R&D Doug Hughes
- RE: [Reactor For CF] Reactor R&D Doug Hughes
- RE: [Reactor For CF] Reactor R&D Shannon Jackson
- Re: [Reactor For CF] Reactor R&D Kurt Wiersma
- RE: [Reactor For CF] Reactor R&D Doug Hughes
- Re: [Reactor For CF] Reactor R&D Kurt Wiersma
- Re: [Reactor For CF] Reactor R&D Sean Corfield
- RE: [Reactor For CF] Reactor R&D Shannon Jackson
- Re: [Reactor For CF] Reactor R&D Sean Corfield
- RE: [Reactor For CF] Reactor R&a... Shannon Jackson
- Re: [Reactor For CF] Reactor R&a... Sean Corfield
- RE: [Reactor For CF] Reactor... Shannon Jackson
- RE: [Reactor For CF] Reactor R&D Doug Hughes
- RE: [Reactor For CF] Reactor R&D Shannon Jackson
- RE: [Reactor For CF] Reactor R&D Shannon Jackson

