Re: Object-relational impedence

From: Robert Martin <unclebob_at_objectmentor.com>
Date: Mon, 3 Mar 2008 16:48:10 -0600
Message-ID: <2008030316481044303-unclebob_at_objectmentorcom>


On 2008-03-03 12:46:09 -0600, topmind <topmind_at_technologist.com> said:

> It depends on how you use the DB. In Robert Martin's version of the
> payroll application, the DB is almost reduced to a dumb filing system
> ("persistence layer") because the app code does all the work. However,
> in my version:
>
> http://www.geocities.com/tablizer/payroll2.htm
>
> I *leveraged* the DB so that much if not most of the work is done by
> the database and queries *instead* of the app code.

Well, that might be a bit of an exaggeration. Here's just one part of the code in your example:

<cffunction name="printStubs">

    <cfquery name="stubQry" datasource="#dsn#">

        SELECT *
        FROM payStubs, employees, payItems
        WHERE empRef = empID AND payItemRef = payItemID
        ORDER BY payDate, empRef, lineNum
    </cfquery>
    <!--- <cfdump var="#stubQry#"> [for debugging] --->
    <h3>Pay Stub Samples</h3>

    <cfset shadeClr = "##f0f0f0">
    <cfoutput query="stubQry" group="empID"> <!--- outer group by empID --->
        <cfset sumPay = 0>    <!--- init --->
        <hr>
        <table border=1 cellpadding=2 cellspacing=0>
            <tr>
                <td bgcolor="#shadeClr#" width="25%">Name:</td>
                <td colspan=3>#stubQry.lastName#, #stubQry.firstName# 
#stubQry.middle#</td>
            </tr>
            <tr>
                <td bgcolor="#shadeClr#">Empl. ID:</td>
                <td colspan=3>#stubQry.empID#</td>
            </tr>
            <tr>
                <td  bgcolor="#shadeClr#">Payroll Date:</td>
                <td colspan=3>#stubQry.payDate#</td>
            </tr>
            <!--- column headings --->
            <tr bgcolor="#shadeClr#">
                <th colspan=2>Item<br>Description</th>
                <th>Reference<br>Value</th>
                <th>Pay<br>Amount</th>
            </tr>
            <!--- for each line item --->
            <cfoutput>
                <!--- skip line if zero-amount suppression is on --->
                <cfif Not (stubQry.displayOptions Contains '(supprzero)'
                    And stubQry.amount EQ 0.00)>
                    <tr>
                        <td colspan=2>#stubQry.lineDescript#</td>
                        <td align="right">
                            <cfif stubQry.sumMult is 0>
                                #stubQry.referenceAmt#
                            <cfelse>
                                &nbsp;
                            </cfif>
                        </td>
                        <td align="right">
                            <cfif stubQry.sumMult NEQ 0>
                                
#numberFormat(stubQry.amount,"-9,999,999,999.99")#
                            <cfelse>
                                &nbsp;
                            </cfif>
                        </td>
                    </tr>
                </cfif>
                <cfset sumPay = sumPay + stubQry.amount>
            </cfoutput>

            <!--- Total Line --->
            <tr>
                <td colspan=3 align="right"><b>Total</b></td>
                <td 
align="right">#numberFormat(sumPay,"-9,999,999,999.99")#</td>
            </tr>
        </table>

    </cfoutput>
</cffunction>

That's a lot of processing code.

However, I think your point is not completely invalid. You *did* use more database facilities than I did. Was your code smaller or better? From the above I would say that it was not better. In the C++ example from my book "Agile Software Development, Principles, Patterns, and Practices" you won't see any methods that are even a quarter as long as what you have there. As for whether it was smaller, it's hard to say because the two programs don't do very similar things. You used a very different set of requirements than I did.

Still, your point is valid in that I purposely pulled out any kind of SQL from my example, and made use of C++ code rather than database tools -- to the extent that I even did a linear search through all employees rather than using the database to efficiently query them. This was done on purpose because the book is an exposition on OO design principles as opposed to database principles.

You might complain that a book about writing good software *should* have database concepts mixed in with it. I sympathize, but authors must make choices, just as you did in your example.

-- 
Robert C. Martin (Uncle Bob)  | email: unclebob_at_objectmentor.com
Object Mentor Inc.            | blog:  www.butunclebob.com
The Agile Transition Experts  | web:   www.objectmentor.com
800-338-6716                  |
Received on Mon Mar 03 2008 - 23:48:10 CET

Original text of this message