Title: Message
Personally, I think it has much to do with your error handling techniques. 
 
To speak directly to the metaphor of 'Contract' though would suggest that if functionA requires valid data passed in, then not passing in that valid data is a violation of the contract.  Given that, I would throw an exception, which keeps the function pretty atomic and portable.  Also as someone mentioned, you could have a validateSSN() in addition to formatSSN(); how you choose to nest or not nest these is up to you of course.  Perfectly reasonable to have validateSSN() be called from within formatSSN() to ensure validity, but I believe that validateSSN() is more appropros when validating form input, before you even get to the issue of formatting it for display.  If approached this way, then you would KNOW that the ssn is valid and formatSSN() wouldn't require additional error checking logic.
 
The key is what/who is responsible for handling the violation of the contract, and that should be the calling code, since there may be instances where valid data is vital (applying for a loan or cc) or purely incidental (arbitrary user information).  The function itself shouldn't know anything about the context in which its being used per se, its a cog, not the engine.  Using the Contract metaphor, if I have a contract with a painter to paint my house, and he doesn't paint the bedroom (violating the contract), is this a critical abortion of the entire process?  If yes, stop all work until the bastard paints the bedroom.  If no, he can paint the bathroom to make up for it.  If 'I don't care' then do nothing cause I'm just as happy to see the leathery faced chain smoking bucket head get the hell out of my house and thats worth it.  Its not the fault of the paint brush, and it shouldn't be in a position to determine the severity of the violation or what to do about it.
 
In my own applications I think I'd be inclined to literally throw exceptions (since I tend to rethrow and let the errors bubble up), but it could also take the form of returning -1 for numeric return values, or empty string for string functions, etc.   Not really a fan of this, since these may be valid return values depending on the function (and policy decisions that -9999999 signifies 'error' never appealed to me). 
 
My own opinion:  throw exceptions and let the calling code determine if the severity is worth addressing.
 
Kevin
 
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dawson, Michael
Sent: Tuesday, November 30, 2004 12:56 AM
To: [EMAIL PROTECTED]
Subject: [CFCDev] Intelligence of Functions

I was reading a nice book about OOP techniques in Java.  One of the concepts that stuck out, to me, was the notion of "Design by Contract".
 
Basically, this means that a service (UDF, in my example) expects certain input and returns expected output.  The client (any calling code, in my example) is required, by "contract" to supply correct information to the service in order to get the desired results.
 
This is easily understood.  Now, my question comes with "how smart" should a UDF be, yet still not try to do too much.
 
My example is displaying a Social Security Number on a page.  I may need to output it in two different manners:
Normal: 123-45-6789
Masked: xxx-xx-6789
 
Now, we all know that SSNs are nine-digit numbers.
 
QUESTION 1:
What should happen if I pass a number that is not nine digits?  Should it throw an error or just return the passed value back to the page?  Look at it in both contexts of normal, formatted, SSN output as well as the masked SSN output.
 
QUESTION 2:
Should my UDFs prepend leading zeros to the beginning of any number that is less than nine-digits?  Or, should that have been done prior to the UDF usage?
 
One solution is to have the UDF do a lot of code in itself, but then, it would limit its usage later on.  The other solution is to create multiple, smaller UDFs that do only a single task, but then that would require more UDF nesting.
 
Thanks
M!ke

Reply via email to