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.

If getXyzRecord was changed to getXyz by default, then we wouldn't have to adapt Reactor specific method names for our business objects. If for some reason we decide to switch to a persistance framework that doesn't call its business objects "records" we won't be stuck with that method name through out our code. I really view the record objects as proxy objects to plain old bean. As Shannon pointed out we could just create a custom method but should Reactor promote using a special naming convention?

Mach II does have API but we limit use of that API to our Mach II listeners which serve as controllers. All they do is deal with processing http requests to the application. Our service layer is designed to be used by several applications some of which are Mach II others are setup in Fusebox. In addition our service layer is designed to be called via flash remoting and web services. We would like to hide all of our persistence logic behind our service layer. With this setup Mach II's API doesn't leak into other layers of our application.

Doug (and other Reactor contributors), I think you have done an awesome job with Reactor. We are very lucky to have a great community that provides open source frameworks. We like Reactor but we thought we would start some discussion on this subject now before the 1.0 release when the API gets locked down. I think it is great that we can have healthy debate on this list as we share our techniques and get every one's feedback. :)

--Kurt


On 3/22/06, Doug Hughes < [EMAIL PROTECTED]> wrote:

Shannon

 

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
Sent: Wednesday, March 22, 2006 3:46 PM
To: [email protected]
Subject: [Reactor For CF] Reactor R&D

 

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 ColdFusion Mailing List -- [email protected] -- Archives at http://www.mail-archive.com/reactor%40doughughes.net/

Reply via email to