What`s Code Without Variables? - Best Practices for Using Variables and Data Structures
(Page 4 of 4 )
Use the best practices described in this section when you reference the data structures you have declared in your programs.
This logic is driving me crazy!
Replace complex expressions with well-named constants, variables, or functions.
Problem: Business rules can be complicated, and it’s hard to keep them straight.
While it’s possible to train our brains to manage and keep straight a very large amount of information, we all have limits. Unfortunately, application requirements don’t always respect those limits. You’ll often encounter business rules with 5, 10, or 20 individual clauses in them. And you’ll have to put all of those together in a way that works and, ideally, can be understood and maintained. And therein lies the rub.
Consider the code below. I need to figure out whether an employee is eligible to receive a raise, so I faithfully translate the various conditions from the requirements document to the code:
IF l_total_salary BETWEEN 10000 AND 50000
AND emp_status (emp_rec.employee_id) = 'H'
AND (MONTHS_BETWEEN (emp_rec.hire_date, SYSDATE) > 10)
THEN
give_raise (emp_rec.empno);
END IF;
This code compiles, I do some testing, and it seems to be working all right, so I move on. A week later I come back to this area of my program to fix a bug, and realize: Wow, that’s hard to understand! And because I can’t immediately understand it, I also can’t be very confident of what it does or whether it is correct.
Lucky for me, I don’t need to understand that code right now. It’s not part of the bug. But it does distract me, and make it hard to find and read the code that was causing the problem.
Solution: Simplify code to make the criteria for the business rules more obvious. So, I put my bug-fixing on hold for a moment and create a local function named eligible_for_raise and simply move all the code there. Then my main execution section is simplified to do nothing more than this:
IF eligible_for_raise (l_total_salary, emp_rec)
THEN
give_raise (emp_rec.empno);
END IF;
With this approach, I have hidden all the detailed logic behind a function interface. If a person working in this program needs to get the details, she can visit the body of the function.
Yet this function still has all the same problems of readability and maintainability, so the best approach of all is to go inside that function and make the criteria behind the rule more obvious:
FUNCTION eligible_for_raise(
total_salary_in IN NUMBER
, emp_rec_in IN employees%ROWTYPE
)
RETURN BOOLEAN
IS
c_salary_in_range CONSTANT BOOLEAN
:= total_salary_in BETWEEN 10000 AND 50000;
c_hired_more_than_a_year CONSTANT BOOLEAN
:= MONTHS_BETWEEN (emp_rec.hire_date, SYSDATE) > 10;
c_hourly_worker CONSTANT BOOLEAN
:= emp_status (emp_rec.employee_id) = 'H';
l_return BOOLEAN;
BEGIN
l_return := c_salary_in_range
AND c_hired_more_than_a_year
AND c_hourly_worker;
RETURN NVL (l_return, FALSE);
END eligible_for_raise;
Certainly my code has gotten longer, but now it is so much easier to understand. I don’t have to deduce or infer anything from the code. Instead, it tells me, directly and explicitly, what is going on.
Please check back next week for the conclusion to this article.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |
|
This article is excerpted from chapter four of the book Oracle PL/SQL Best Practices, Second Edition, written by Steven Feuerstein (O'Reilly, 2007; ISBN: 0596514107). Check it out today at your favorite bookstore. Buy this book now.
|
|