Design Patterns Are Accidental
Design Patterns Are Accidental
If neither essence nor matter is to be, nothing will be at all.
Join the DZone community and get the full member experience.Join For Free
Discover how you can take agile development to the next level with low-code.
Henrik Warne's list of programming quotes was recently published on DZone. One quote was from Fred Brooks, longtime head of Computer Science at the University of North Carolina, just around the corner from DZone itself. The quote was: "Much of the essence of building a program is in fact the debugging of the specification."
"Essence" is a word we use every day to mean "the heart" or "the center" of something, but as he explains in "No Silver Bullet", the essay from which this quote comes, Brooks himself uses that term in the same way that Aristotle used it. It means something absolutely required, something "inherent" or built into programming, as opposed to something "accidental"; that is, something that is part of building a program today, but may not be part of programming tomorrow.
So what Brooks is saying in his quote above is that debugging of the specification, which I would define as "figuring out exactly what it is that we're supposed to be building here" is a necessary task, maybe the necessary task in programming. Which makes sense.
So what kind of things would we consider "accidental"? By accidental, we don't mean things that are chosen randomly, or for no reason at all. Instead, we mean things that could be changed while still resulting in the "same program" from the perspective of the user or another program. It occurs to me that one answer is "design patterns"; those design approaches within the software that we use to make the implementation clearer and easier to maintain, but that do not in themselves affect the program we're writing.
My previous article on design patterns got a great comment from Serguei Meerkat pointing out that some developers see design patterns as essential to writing a good program, and that "the result is usually an unreadable and unmaintainable code". I believe that this is because those pattern-happy developers put the cart before the horse. By focusing on something that is accidental to the program, like "what design pattern shall I use today?" rather than something essential like what the program must do, they get stuck stuffing the essential complexity of the program's job into the wrong-shaped box of the chosen design pattern.
It's like the novice programmer in The Tao of Programming:
A novice programmer was once assigned to code a simple financial package.
The novice worked furiously for many days, but when his Master reviewed his program, he discovered it contained a screen editor, a set of generalized graphics routines, and an artificial intelligence interface, but not the slightest hint of anything financial.
When the Master asked about this, the novice became indignant. "Don't be so impatient," he said, "I'll put in the financial stuff eventually."
Of course, "accidental" parts of a program are very important. The choice of programming language can make it easier or very much harder to write a program. The choice of algorithms and data structures can be the difference between poor performance and excellent performance. And the use of design patterns can mean the difference between a program that everyone hates to maintain, and a program that lasts a long time and somehow seems to anticipate the new features that are thrust upon it.
Also, "accidental" items like design patterns and programming languages, exactly by virtue of being "accidental", are applicable to a broad range of potential programs, so learning them pays dividends beyond just the current job. A developer who works in the financial sector yesterday and developing social media apps today has a head full of financial knowledge that isn't useful any more, but is probably still using factories.
So just like in my article about Looking Along the Beam we have to try to keep both perspectives. But in this case, one of the perspectives is superior to the other. As we put together the architecture and design of a system, it absolutely should start with the "essential" elements of the system we're making.
I remember a project from many years back where there was already a clear, established way in which human beings performed some work. The system we were building was one in which computers were asked to just automate that existing work. The human beings already had perfectly clear terms to refer to the parts of their job. (Sorry, details stripped to protect the national security.)
When the development team came in and established the "architecture", it consisted of "Buy Big Company Product A", "Buy Big Company Product B", and "Wire Product A to Product B". One top-level model in the system was labeled something like, "Product to Product Interaction". Lost was the set of nouns and verbs that the human beings were using to perform this work every day.
As a result, it became impossible to figure out what part of the "architecture" was responsible for any of the essential tasks that needed to be performed. It took a long time for that system to drag itself out of that approach. Starting with design patterns and shoehorning in the real system seems like a similar error.
Opinions expressed by DZone contributors are their own.