Similar: How was programming done 20 years ago?
OOP is quite fashionable nowadays, having its roots in Simula 67 in the 1960s, and later made popular by Smalltalk and C++. We have DRY, SOLID, many books about design patterns in the object-oriented world.
But what were the main principles in programming prior to the OOP paradigm wide adoption? And what were the major design patterns?
6
I was a Cobol developer before I learned Java. I’ve developed for over 35 years.
Back in the days of procedural languages, most of the processing was done in batch. Go back far enough in history, and even program compilation was done with a deck of punch cards in batch.
Contrary to Kilian Foth’s assertion, we had design patterns back in the 1970’s and 1980’s. There was a certain way to code a multi-file match/merge in Cobol. There was a certain way to code adding transactions to the master (tape) file in Cobol. There was a certain way to code report generation in Cobol. That’s why IBM’s Report Writer never really gained traction in a lot of Cobol shops.
There was an early application of the DRY principle. Create lots of paragraphs so you don’t repeat yourself. Structured coding techniques were developed in the 1970’s and Cobol added structured words (verbs) to the language in 1985.
Generally, when we wrote a new Cobol program, we copied an old Cobol program and changed the names to protect the innocent. We almost never coded a Cobol program from a blank sheet of paper or a blank screen. That’s a big design pattern when you can copy and paste entire programs.
There were so many Cobol design patterns that it took years for a Cobol programmer to learn them all. That’s one reason that the Cobol programmers today are, for the most part, still using 1985 syntax.
7
“Design patterns” in software didn’t exist in the era you talk about, because the concept hadn’t been invented. This is not me being flippant – it actually is the reason; being called a recognizable name is what makes a Design pattern a “Design pattern” rather than just code that you keep using in one form or another (e.g. a “Factory” rather than “the kind of static class that I like to use rather than an assortment of constructors”) and the concept itself is no exception.
That said, of course there were things that fulfilled exactly the same role in the work of practitioners as design patterns do now. But you’ll be disappointed in hearing about them: typical “trick of the gurus” in those days were things that are quite boring to us now – e.g. singly-linked lists, loops controlled by an index incremented on each iteration, clever “accessor” methods that seem to do nothing but give you leeway in changing your mind about implementation details later.
That’s right, things that we now take for granted – that are sometimes even part of the languages we use – used to be advanced (and sometimes jealously guarded) concepts known only by more experienced coders. Chances are, almost everything not utterly trivial that you learn in a basic programming course today went through a phase where it was the moral equivalent to a “Design pattern” to the practitioners of the age. Software construction may not be a rigorous engineering discipline yet, but if you study the state of the art of the 50s and 60s, you can’t deny that it has come an enormous way since its beginnings.
3
The previous big paradigm was structured programming. Instead of UML, there were a variety of different diagrams (flow charts, data-flow diagrams, structure charts, etc). Development was mostly top-down, and followed a process of functional decomposition. One of the basic ideas was that your program structure should resemble a diamond: The main module at the top, fanning out into high-level control modules, which invoked routines in lower-level modules. These lower-level modules built on still lower-level modules, all of which (theoretically) eventually converged on a handful of basic I/O routines. High-level modules were supposed to contain the program logic, lower-level ones were more concerned with data integrity and error handling.
Important concepts introduced during this time were information hiding, modularity and high cohesion/low coupling. See the works of Dave Parnas for some seminal papers on these topics. Also check out the work of Larry Constantine, Tom DeMarco and Ed Yourdon.
1
I suppose one large one (besides structured programming itself) was the concept of passing a handle around – in OO you have an object and it contains state and functionality. Back before OO, you’d have a load of independent functions, and you’d pass a handle to some state between them – a cookie if you like. This gave you OO principles without actually having OO.
You can see this a lot in old Win32 code, you’d pass in a HANDLE which would be an opaque type representing some state allocated in the Windows kernel. You could it yourself by passing a pointer to a struct you’d previously allocated as the first parameter to functions that operated on that data.
3
Since nobody has mentioned the obvious one yet: one big design pattern in the procedural era was Object. Like many popular design patterns before (e.g. Subroutine) and after (e.g. Iterator), it became so popular that it even got language support.
A “finite state machine” may count as a Pattern, and FSMs were written (e.g. for communications protocols) using pre-OO languages.
Also “interrupt handlers” and TSRs used to be popular e.g. on DOS.
Terms like “Spaghetti Code” and “Single Point of Exit” are actually throwbacks to that era. Nowadays we call code we don’t like “spaghetti code”, but really that’s a reference to code tied together (badly) with GOTOs and JMPs.
(Today we suffer “ravioli code”, in which the code is like a bunch of unrelated, tightly packaged classes, much like a plate of ravioli. However, some OO experts ask justifiably, “But isn’t that what OO is supposed to look like?”)
“Single Point of Exit” today is just a frustrating refactoring roadbump. A lot of devs I talk to haven’t even heard of it, and are aghast when I explain it. But in the old days it meant don’t jump out of a code block suddenly & into spaghetti code. Jump forward to the end of the logic, then exit gracefully.
Stretching my memory way, way back, I seem to remember that the idea of bundling code up into procedures was a big leap forward. The idea that you could package procedures into inter-operable, reusable Modules was kind of the Holy Grail of programming.
EDIT: “Self-modifying code” was also a pattern used notably on the original Doom. That’s where the program would actually overwrite its instructions with faster instructions based on it’s state. When I was a tyke taking a programming course at the Science Museum, my instructor warned us sternly, “Don’t write self-modifying code!”
EDIT EDIT: However, before the Internet, word travelled a lot more slowly. The idea of implementing Algorithms and Data Structures used to be a much bigger deal. Today I do sort all the time without even knowing what sort I’m using. But back then you had to code it up yourself. I remember one article talking about programming challenges that used to take days that today we knock out in a half hour, or less. So really concious “algorithmic” and “data stucture” programming would probably be on the list, much more than today.