Writing software can often take you down 3 separate paths. Speed, flexibility, or obviousness are classic goals in writing software. Speed is how fast the program runs or how soon a certain part of the program finishes its work. Flexibility is the ability to adapt the program or a part of the program to new work, behaviors, and conditions. Often, you can judge successful flexibility based on the time it takes or the level of effort needed to adapt the program. Obviousness is how a line of code can be understood and perhaps how well an entire program can be known in just a few readings of the program’s code.
The goals stated above are not the purpose of the program but the quality criteria established by those who build the program. The purpose of a program is to solve a problem, establish a process, or create new opportunities. Quality criteria goes to how well a program addresses its purpose matched to the operational prerogatives of the program designers.
It does seem that I am setting these quality measures in isolation and sometimes they are pursued that way. Some programs have to be exceedingly fast to the exclusion of all other measures. Most programs written in IT departments, for the enterprise, put a premium on adaptability over speed as business evolves often every few months. Obviousness then usually sits towards the end of the acceptability criteria scale in terms of schedule appropriateness. The reality is that these criteria exist together in many programs. As they interact, they may be in conflict or in some kind of coherent alignment.
It is an explicit judgment call as to what extent each design criterion is emphasized. One can take from the other in what is called a design trade-off. Call it engineering, call it architecture, call it design. While there exists specialized descriptions of those activities (engineering, architecture, and design) in the creation of software, the major criteria of speed, adaptability, and obviousness cuts across all.
Skills individuals have in writing software are defined by the emphasis they place on one or more of these criteria. The knowledge gained in different areas of computer science can influence this. Some will lean more towards obviousness, most will choose adaptability, and a few will choose speed. Then there are those who strive for a fusion of all criteria. The resulting program in both its external representation and its internal structure is directly linked to range of technical criteria addressed by those who designed and/or assembled the program.
You then have a class of programs that do benefit from the convergence of these criteria. Video games. When you hear those words, you may think recreation, entertainment, and perhaps an indulgent waste of time. What I hear is something different. Video games represent a kind of technological calisthenics. They push the envelope of integrating multiple areas of technology into one solution. Those who achieve the ability to produce an entire game solution might achieve technological insight of a comprehensive kind.
Merging network programming, graphics, multimedia, multiple input methods, artificial intelligence, very tight file and data management requirements that all have to occur within milliseconds at best. It is a set of requirements which offers a set of choices between adaptability, obviousness, and speed that can give one a better understanding of those choices.
Those who play games have the opportunity to enhance their reaction time, their brain response to multiple stimuli, and improve the efficiency of their ability to interpret fast-moving complex information. I don’t play video games, I stopped about 5 or 7 years ago, but I do occasionally study the technology behind video games. I am not really interested in writing one but what I appreciate about game technology and design is how it can be applicable to other kinds of technology.
Any system that presents information visually using colors, lines, graphics, and then requires periodic or frequent interaction can benefit from the lessons, techniques, and perspective born out of video game technology also called simulation technology. By the same standard, even batch and network systems may be enhanced through the granular automated decision processes found in the realm of simulation technology.
The question then is how do you begin to reason about quality distinctions within software as they implicitly echo out in how the software operates. Why was adaptability better in one situation where higher speed was given up? Why was speed so important that obviousness had to give way to a more obtuse technical expression that runs faster? Why was the line held firmly at obviousness to the exclusion of speed and adaptability? More realistically, where do you prefer to make that fine transition from obviousness to adaptability to speed and so on throughout the solution? At the top of your program, you may represent the most sublime expression of function in a brilliantly expressive way. As you travel through the program’s hierarchy of structures, functions, and data, you begin to see shifts from exceedingly consistent obviousness to great adaptability with heavy pockets of optimization for speed. Occasionally, though, the structure does not hold in some parts and the need for speed or stronger adaptability strikes mercilessly.
Before any of this becomes an issue though, you have to understand speed, understand structure, understand data, and understand design, function, and system architecture. The components of system representation and execution must be understood, personally trialed before they can be reasoned about confidently. Robert Nystrom does not cover the background in-depth, in his book, Game Programming Patterns. He deals with the structuring mechanisms that encode system representation.
What Robert Nystrom does is present a summary of software design in which he cites many of the details relevant for a given design approach. The book is about the thought process, gentle analysis, and guidance around certain design possibilities for a certain part of software. His work is thorough and actionable and would be a leading document for coordinating in one book the general knowledge one would develop through experience for how to put a program together for production use.
The first section of the book talks about software architecture. It is about the trade-offs presented so far and the gradual shift away from a program that may consolidate functions in a way that may unintentionally obscure structure, process, and flow. You do not always need excellent design and I like how the author clarifies this. Basically, the first section is a very honest discussion about software design. When you need to reason about better design though, it helps to refer to a common vocabulary and description of such.
There is an original book on software design called Design Patterns by a group called the Gang of Four. I read that book in 2001 and it shaped by thinking about software for nearly 10 years until I started moving away from it. I struggled with the original Design Patterns book in 2001 when I read it because I did not know C and C++ at that time but I did not let that stop me from understanding the intent of the code examples presented. More useful to me was the text of the 1994 Design Patterns book that gave me a more relevant foundation for software development for the technology I would use months later. My roots in software development is in Procedural Programming but I got out of that into Object Oriented Programming which I saw as a more organized approach. The 1994 Design Patterns book that I read in 2001 gave me a better way to think about objects in which I could take simple objects and combine them to produce more complex structures that met the design challenges of the time. It is one thing to read about Object Oriented Design, which I did, and quite another to formulate how objects can be defined through classes in such a way has to solve a problem with much greater obviousness that moves you further towards greater software adaptability.
Sometimes, this does not work. There are situations in which universal software design patterns are not appropriate at all. I am not going to talk about that right now. Rather, what I can say is that it is possible to take software objects structures and software design patterns for granted. That is to say, you read the 1994 Design Patterns book, several other books on software design patterns and, most especially, Martin Fowler’s Patterns of Enterprise Architecture, and one day find that you are using design patterns intuitively and now have totally forgotten the origins of what you do or why you do what you do. That is where I ended up.
It is good to find a book that covers old ground again in a more up-to-date way that is cleaner, clearer, and better aligned to the conditions of today. Robert Nystrom does well to restate the classic software design patterns in conventional language that also accounts for the realistic scenarios to which those patterns could apply. He does not assume that the patterns are free of context because in reality, they are not. He does help sustain the relevance of software design patterns as a common vocabulary about the structure of software, at least in corporate IT and certain segments of commercial software development, and he makes the topic of software design, or at least, how you put a program together in concept more accessible through a very accessible discussion supported by well delivered examples.