Real World Benefits of Iterating Business Objects over Recordset
In this site, the calculation for product price is extremely complex and requires about 30 lines of code. Unfortunately, the client wants product search, product list and product detail pages to display the price. What to do?!
In the bad old days (pre-OO), my search, product list and product detail pages would have all called the same UDF or custom tag. Luckily I have an iterating business object for my product so I can put all of the necessary code into getPrice() and whether I load it up with a single record or a collection, I can still use the same getPrice() method to encapsulate the code to calculate the price.
I would be interested to hear how anyone who uses recordsets for lists and beans for single records would handle this (the calculation is too complex and too likely to change for me to want to put it into the database).
Of course you could put the code into the service layer, looping through the query and updating it before sending it out, but then what do you do with your bean? Do you duplicate the code in the bean and the service (yuck!) or run the bean query through the same transformation before loading it up? And if you do all of the calculations in the service layer and are guaranteeing all of your getters to be dumb, aren’t you losing one of the main benefits of using beans? Why not just return a recordset for single and multiple records?
Input appreciated!!!





Let the database handle the data. A view or stored procedure would be effective.
I considered that possibility, but I have made the decision not to put these kind of business rules into the database. If I wanted to change db it'd complicate things, business rules change so my view or SP code would become an active part of my application, and in general while I think it can be convenient to put business rules into a db I prefer keeping them in the beans.
This also means that if I decided to support a non-relational persistence mechanism (XML files, perhaps) I wouldn't have to add a duplicate copy of my pricing business rules to the ProductXMLDAO.
While I think there are use cases where putting a lot of heavy lifting into a DB is acceptable, on the whole it's an approach I'm trying to get away from. I typically only do things in the db that it makes no sense to do in the application such as returning only 20 records from a list of 50,000 rather than pulling them all down the wire and displaying only the subset. I also use the db to do aggregations and reporting that again would not be sensible from a performance perspective to do in memory on the CF server.
Other than those kinds of special cases I tend to prefer to keep my business rules in my beans. Especially as this isn't handling the data - this is handling the business rules to apply to the data at runtime and I'm not sure that's really the job of my persistence mechanism.
Best Wishes,
Peter
No problem. I just wanted to live with my design a little before I posted the code. Fact is, the base bean I threw together in just a few minutes seems to be working pretty well. The code isn't fancy, but I'll get something posted up this evening or first thing tomorrow - as soon as I get a moment. Big deliverables today :-<
Best Wishes,
Peter
Where performance is the primary driver or where you have business logic that needs to be exposed to multiple 3GLs, putting the code in the db makes sense.
In most other cases I think it is a horrible idea. When we get a programming language and IDE for db code that is as rich and powerful as those available for languages such as Java or c# I may change my mind. For many projects, developer productivity and maintainability trump performance and typically those are better in a scripting or general purpose programming language than in SQL.
I can only comment on MS SQL so I am a little biased. I havent found any limitations in writting stored procedures, triggers or functions. Since one is not building Objects or any OO programming in TSQL an advanced IDE is not needed. My point is just about the data. Logic youre right, Objects absolutely stick with Java and ColdFusion. But for data recordsets and functions go with the power of TSQL. I believe that Query analyzer is an advanced IDE that will help you create some awesome Stored Procs that will tear apart anything that Java or CF can do regarding the DB logic layer. Mind you I am simply speaking about what TSQL was meant to do, by all means we dont want to create our app in TSQL but for gathering data you just cant beat it.
I do know where you are coming from. I've worked quite a bit with MSSQL from 7.0 through 2005 and for a long time I considered focusing my code generation on generating stored procedures so I could encapsulate all of the business logic in the db level. After going down that route and speaking to many others who have done so I decided it wasn't a good approach for my use case.
There are many potential downsides to moving the business logic to a db. In larger shops, deployment can be an issue as you may not have access to the servers except via a DBA group that will want to spend weeks verifying the integrity of the simplest change. Also, I still don't think the UDE support for writing T-SQL compares with the kind of code completion and (in languages like Java and c#) refactoring support that is available in (say) InrelliJ or Eclipse.
However, in the end, here was what made me decide to keep the database dumb as a general rule. Sometimes a smart getter will be something that can be accomplished simply in a view or SP - for example providing a "fullname" value when the actual columns are firstname and lastname. Others are a little more complex (such as returning Age based on DateofBirth) but still well within the bounds of SQL. However, what happens for a getPrice() method for a product where the price depends on the total orders by that user over the last rolling 12 month period and those of all of the other users within their buying groups - requiring complex joins between multiple order item and order user, user group and various discount group tables? From a performance perspective you could argue that it will probably be more performant in SQL, but if there is a lot of conditional logic in addition to the set based operations, you might want to be able to break down the code into component parts and while UDFs and SP's calling SPs can be used, I'd rather keep such complex busienss logic in my 3GL programming/scripting languages.
However, some would look at that and think it was a perfect example of the benefits of putting business logic within SQL as it will be more performant and available independent of the programming language you choose to use. The final nail in the coffin (for me) was when I asked, what if the smart getter needs to access third party web services? For example, I want to be able to getShippingPrice() for an order and that is going to require either finding a way to write a SP that can call a web service (which even if possible is something most supporters of SQL would probably agree isn't exactly what it was designed for). I decided for my use case to go for a consistency of having all of my business logic (including smart getters and setters and data validation) within my business objects. If performance was a concern or consistency wasn't such a big thing for my specific use case I can understand why someone would decide to put some of that logic in SQL and why it could be a valid choice, but it's important to think through all of the implications.
I'll also throw out the "what if you change db vendor" but to me that is a pretty bogus argument. If you have your logic in SP's, you just WON'T change db vendors, and thats a perfectly valid approach. In fact, I wouldn't be surprised if most shops changed their programming languages more often than their db vendors which would (if anything) support the argument for putting ore business logic in the db - especially with the potential wave of polyglot programming that many seem to be envisioning (although to be fair, you could also just put all the model login in Java and then call it on the JVM using come combination of ColdFusion, Java, Jython, JRuby and the like.