I read a very interesting post on the internal IBM blog site about disciplined (quelle horreure!
) PL/SQL programming. I was inspired to repeat the key points that Carmine Marrone from Brazil made in so far as they related to ANY programming, but especially SPL and to a lesser extent, 4GL. It's not rocket science, but sometimes we all forget the basics! In fact, I thought very hard about whether this post didn't constitute "teaching grandma to suck eggs." But I've seen so many apparently clever people write such bad code that I thought I'd put it out there anyway. The worst that can happen is that everyone is already doing all this. The alternative is that some people might find their lives getting easier!
I have discovered that it is never too late to find - and follow - new paths to writing better code. Some time ago, the quality of my code has improved significantly; this improvement has come mostly from setting some simple rules and then following them in a disciplined way.
It's true, back when my day job was to be a 4GL programmer, I was a damn good one. No false modesty here! But it's never too late to do stuff even better. Never think you know it all!
I met a bloke who taught me a couple of things that lifted my code even higher. I was chatting to a mutual acquaintance who said: "His code is so readable, it's like a Stephen King novel." And this is the central matter of Carmine's blog post: code readability.
This article offers four pieces of advice for novice and experienced ... developers; follow any of these suggestions and your code will improve. Follow all of them, and you likely will be struck by the sudden realization that you are a much better programmer than you ever thought possible.
This is absolutely true: you don't have to adopt all these points, adopting any one of them will make you a better programmer. Adopting all of them will help massively. If you're already doing them all, you're doing very well indeed!
I cannot, through this blog article, change the fundamental dynamics in your development team. I have, therefore, chosen the following points of advice carefully. You will not need to obtain management approval to implement any of them. You won't have to get everyone on your team, whether it's large or small, to agree to the same coding guidelines. Instead, you can concentrate on doing nothing more than transforming your personal coding experience by following these suggestions:
1. Follow naming conventions as though your life depended on it.
2. Break your SQL addiction: The less SQL you write, the better.
3. Keep your executable sections small: Say goodbye to "spaghetti code."
4. Find a buddy: Come to love the idea of having someone looking over your shoulder.
It's true that no-one can change the behaviour of the entire group. Your best bet is to do what you can for yourself and hope that improvements you may find inspire your colleagues (or at least give you an edge when it comes to bonus or promotion time!)
1. Follow Naming Conventions
If you establish and follow rigorously a set of naming conventions, particularly for your application components, you will be able to save lots of time.
Of course, the idea of following naming conventions is nothing new, and it probably sounds boring to you.
Indeed, the whole business of establishing naming conventions can be incredibly nit-picky. I remember, for example, we had a convention that every variable was lower case and every Informix keyword was upper case. But what do you do with sqlca, which is both? Anyway, the chances are that you already have a naming convention. I hope so. If you haven't then you really need to do that, because it lifts the readability and maintainability of your code massively. And once you've gone through the pain of changing your behaviour and it becomes second nature, you'll find that it's really a very good thing. You'll come to hate maintaining your old, pre-standards code.
2. Break Your SQL Addiction
As counterintuitive as this might seem, the less SQL you write, the better. This is strange advice for a [SPL or 4GL] developer, because one of the key advantages of [SPL or 4GL] is the ease of writing SQL statements in your code. This ease, however, is also an Achilles' heel of the language.
Indeed, this seems bizarre. But there is a reason for this assertion:
You can place native SQL statements directly inside ... code; no intermediate layers such as JDBC or ODBC are necessary. Consequently, ... developers generally embed SQL statements whenever and wherever they need them in their application code. So what's wrong with that?
Dispersion of SQL statements in ... code leads inevitably to the following:
* Repetition of the same logical statement, although with different physical representations, resulting in excessive parsing and difficulty in optimizing the performance of your application.
* Exposure of business rules and formulas. There is a good chance that you will include right in the SQL statement logic that implements business rules. Such rules, of course, are always changing, so the maintenance costs of your application rise rapidly.
Of course, just about every ... application you will write is built on underlying tables and views. You need to execute SQL statements. The question is not if, but when and how.
Your application will be much more robust, and you will find it much easier to build and maintain, if you encapsulate your data structures, or hide them behind a layer of ... code
In other words, modularity. Try very hard to make building blocks of code that get called by other blocks of code, whether it's functions in 4GL or procedures and functions in SPL.
Let's look at a simple example. Suppose I need to write a program that processes an employee. The first thing I need to do is get the full name of that employee, defined as "last comma (,) first"; I can then perform the detailed analysis. Listing 1 offers an example of the sort of code I am likely to write in this situation.
It all seems so simple and direct; what could possibly be wrong with this code? An awful lot, actually. Most important, I have exposed a business rule: the structure of a full name. I can test this code, and the application it is built on, for hours. Right after it goes into production, however, I just know that I will be getting calls from users telling me that, in actuality, they need their full names to be presented as "last space first."
Ah, yes. Which of us has not been there? I'll offer an example (which we'll consider pseudo-code, since I've no access to a compiler to test this, but it's just to outline the principle.
Here is a solution to the business problem using "raw" SQL:
FUNCTION process_employee (employee_id_in) DEFINE employee_id_in INTEGER; DEFINE lv_name VARCHAR(100) DEFINE lv_whatever VARCHAR(100)
SELECT last_name || ',' || first_name INTO lv_name FROM employee WHERE employee_id = employee_id_in
CALL perform_detailed_analysis (lv_name) RETURNING lv_whatever
FUNCTION process_employee (employee_id_in) DEFINE employee_id_in INTEGER DEFINE lv_name VARCHAR(100) DEFINE lv_whatever VARCHAR(100)
CALL get_formatted_name(employee_id_in) RETURNING lv_name
CALL perform_detailed_analysis (lv_name) RETURNING lv_whatever
The key difference is that the function that does the name formatting would almost certainly be used in lots of places, so breaking it out into a function means that if the "standard" changes, you only have to fix it in one place.
3. Keep Your Executable Sections Small
Let's face it: All too often, against our better judgment and our latest round of New Year's resolutions, we end up writing spaghetti code: large, endless blobs of meandering code that are virtually impossible to understand, much less maintain or enhance. What can you do to avoid spaghetti?
Actually, the solution is simple: Never allow an executable section to exceed more than 50 or 60 lines. This size allows you to view the entire logical structure of the block on a single page of paper or eyeful of screen, which also means that you can actually grasp the intention of the program and understand it at a fairly intuitive level.
You may well agree with all of this yet scoff at my suggestion that your world could ever be contained in 50 lines of code. You should scoff, because that is, of course, not possible. You will no doubt need more than 50 lines of executable code; the question is where you will put that code and how you will organize it.
You will indeed be able to implement requirements of arbitrary complexity and hew to the 50-line limit, if you:
* Take care to reuse code whenever possible by placing all business rules and discrete chunks of logic in their own programs (usually functions)
* Make extensive use of local modules, procedures and functions that are defined right inside the declaration section of your program
I always struggled to keep massive bits of code straight in my head. If a function or procedure was more than 50 lines long (two screenfuls back in the olden days of 25 by 80 green-screens!) it would have to go out on the printer.
(And don't I miss dot matrix printers for their ability to print stuff out on one continuous strip of paper that you could easily fix to a wall? You young people don't know you're born!)
Small is beautiful, it keeps stuff intuitive and easy to follow. And I'm not going to scoff at this advice either:
Getting a clean compile on such a small program may seem like a small victory, and it is. But small victories such as these — a clean compile, then a simple test, then the addition of a bit more code, another clean compile, and so on — lead to well - constructed programs and a big dose of satisfaction.
Cutting code can often be daunting, especially when you're at the start of an enormous project with tight deadlines. Build a continuous sense of accomplishment by taking small steps that you know have worked. I've heard it called all sorts of new-age wibble, but iterative programming has been around for decades and it works better than anything else out there.
This is programming gold:
4. Find a Buddy
Computers do not write programs; humans write them.
How many times have you sat hunched over your computer, deeply frustrated by your inability to find a bug in your code? First minutes and then hours pass. Finally, disgusted with yourself and feeling like a failure, you poke your head over the top of your cubicle and ask a friend to come over and take a look.
One of three things usually happens:
* As the friend gets up from her chair, all becomes instantly clear.
* Your friend takes one peek at the screen and immediately puts her finger on the problem.
* Your friend doesn't work on your area of the system, so you have to explain what your program is doing. As you step through the logic, the flaw that is causing the bug pops out at you.
The reality is that it's hard to debug your own code, because you are too attached to and too involved in it.
The best solution to this problem is for the development manager to create a culture in which ideas are shared, ignorance is admitted without penalty, and constructive code reviews take place regularly. Such cultural changes are, unfortunately, difficult to achieve. [Ed: And probably only exist somewhere in a writer's imagination!]
In the meantime, I suggest that you take the first steps in helping transform the culture in your group. Seek out another developer, preferably one with more experience than you, and establish a "buddy" relationship: Offer to be a sounding board for that person in case of problems if your buddy will do the same for you. Agree in advance that there isn't anything wrong with not knowing the answer to everything.
Then set a simple rule for yourself: Never struggle for more than half an hour on a bug. When 30 minutes have passed, call your buddy over and put human psychology to work for you, not against you.
The only thing I disagree with is 30 minutes. Usually, if I can't divine the problem within 15 minutes, I'll "phone a friend." No point in wasting time.
I might have a go at discussing comments next![Read More]