I received my daily email from Computerworld with a link to an article titled “What we miss about MIS: 5 old-school ideas that weren't so bad.” Their reminiscence of COBOL and structured programming got me to thinking about many of the complaints I have working with software developers. I don’t mean all software developers. Some I know have really strong heads on their shoulders – others not so much.
I am not longer a programmer by trade, but I often find myself having to review code to debug or to find issues that need to be resolved. The language skills may not be current, but the methodologies are still applicable.
When I first learned programming in junior high school, it was an “anything goes” environment. Since we were learning things from the most basic level, programs were written in a single file. There was no modularity. You ended up with what we affectionately called “spaghetti code.”
Just as punch cards had to be in order when inputted to an IBM System/360, programs ran in sequence based on line numbers. You began by numbering your lines by the tens.
10 PRINT “HELLO WORLD!”
If when testing the program you found a glitch, you inserted the patch between the lines of code using intermediary line numbers.
5 FOR X=1 TO 10
10 PRINT “HELLO WORLD!”
15 NEXT X
This model is fine for a single task. But when you started handling multiple processes in a single application, the code could get confusing. To top it all off, REM statements or comments were considered wasted space. They only increased the size of your file, but were ignored by the compiler.
Over time, I transitioned my knowledge from BASIC, Assembly and Pascal to QuickBasic and COBOL. These compilers required a bit more thinking. No longer were we reliant upon line numbers but on the sequence of the instructions. They introduced a level of modularity to help reduce the effects of spaghetti code and simplifying the debugging of specific routines that were written to perform one function only per module.
COBOL programming introduced a level of structured programming that was beautiful in design and easily applicable to other programming languages. Yet I have found that most of the structure is often overlooked by modern day programmers. In an effort to get programs out the door as quickly as possible, programmers commonly forego the use of hierarchy charts, pseudocode and comments. Doing so leaves future programmers working on the code bewildered and costs the companies employing them tremendous amounts of money that could be saved if a little time is taken initially to ensure the proper methodologies were followed.
There are many benefits to this methodology. The programmer is intimately familiar with their code. The customer has adequate documentation to understand the processes. The programmer is forced to think through the application in a logical format. History of development is maintained to show accountability and discover when possible errors in data first occurred so that they can be repaired more easily.
In COBOL 101, I was taught that before sitting down at the computer a programmer should draw on paper what the screens in the program were to look like. Once those screens are drawn, the programmer develops a hierarchy chart showing all of the processes required for the application. Each box in the hierarchy chart is to serve one function such as writing to the database, requesting input or printing. This allows modules to be recycled in other parts of the hierarchy chart so that the programmer does not have to include the same code twice in the application.
Once the hierarchy chart is completed, the developer should start at the top down writing an outline of how the program should operate in plain English so that others can understand the flow of program execution. This “pseudocode” is then used as the comments in the application at each module level to explain the code that follows. This allows future developers working on the project to understand the thought processes behind the design so they do not need to have access to the original programmer for debugging or enhancements. The pseudocode is interspersed by each routine it describes to make it easy for lay people to follow the code.
Each developer that touches the code should also modify the comments accordingly to assist the next person who modifies or reviews the code. And of course each developer should identify themselves at the top of the module with a date of the revision.
Each module should be visible on the screen without having to page down to view the rest of the code. Since the module performs only one function, this is relatively simple to accomplish. There are some modules that might require slightly longer code, but the overriding rule of thumb to follow is “one module performs only one function.” Once the comments are added, it will most likely be necessary for the module to be two pages in length.
To help accomplish pure modularity and simplicity, the use of GOTO commands is to be abolished without exception. This rule was so strict in college that the use of a single GOTO command would be grounds for an immediate failure for the assignment. Programmers should decide why they are using GOTO. Is it to insert code that was overlooked initially? If so, insert it into the module where it belongs without the use of GOTO. Is it to run a specific sub-function such as error checking? This should be a separate module that is called using a GOSUB rather than a GOTO so that the program can return to normal operation at the point where it left off without the need for a second GOTO command.
There is absolute no viable use for the GOTO command. A programmer who relies on this shortcut should modify their way of thinking. Failure to do so only results in spaghetti code which is no longer acceptable and often grounds for termination.
Now that we have our pseudocode, hierarchy chart and screen shots designed on paper, it is time to sit down and write out the code itself. As with the previous steps, this should be done on paper so that it is well documented and thought out before the programmer even sits down at the computer to type. This entire work product contains complete documentation of the application and its processes that can be handed off to the final customer. This method of documentation is necessary to facilitate code review and future modification by others.
Now that everything is written out, the programmer becomes a typist. If in the course of entering in the program and testing they determine an error in the code, they must not only fix it in the editor but in the written documentation as well.