Continuing from an earlier discussion of software design, many of the Design Patterns discussed in section 2 of the book, Game Programming Patterns are great solutions to a range of design requirements. The section describes 6 of the original 23 patterns from the 1994 Design Patterns book. Those patterns that are discussed are useful for strengthening structure at various levels of a software code implementation consisting of an upper level API, mid level API and low-level implementation. Class types designed for the upper level API and top-level function region of a solution may be well treated by patterns such as Command, State, and Observer.
The author of the book does a great job describing the Command pattern. I see this pattern as a good way to improve code organization. A function may have accumulated more statements than is useful to understand it. Higher code density may be computationally efficient but at odds with adaptability. The Command Pattern may be fundamentally useful for applying the concept of functional decomposition in which you refactor a code heavy function into separate functions that reduces overall code footprint through the elimination of redundancy due to effective code reuse. That is the potential of the Command Pattern I see presented in section 2. Yet, I see evolving the Command Pattern into the State or Component patterns as better alternatives.
The State pattern does not have to imply the retention of state but rather the facilitation of context. Context can involve the representation of state which can be implemented as persistent state or state derived from source data and functions. A fine line exists between the idealized model of the State pattern and the definition of a type that is a User Defined Type. It is a difference of generality versus specificity. Even though the State pattern can shift into a more specific direction, the pattern itself is a great place to start in the design of a logical execution unit.
The Observer pattern is an immensely useful concept especially for graphical systems covering web, desktop, mobile, and embedded display not to mention enterprise service bus. It is a concept you will become well acquainted with the more time you spend with mature graphical application systems using some form of event dispatch and signaling registration. The Observer pattern is a highly effective productivity mechanism. It is a way to not only decouple participating functions of a process in a clean way but it is also a mechanism for code productivity in large, complex systems. The Observer pattern helps enable the concept of Rapid Development alongside inheritance and polymorphism in object-oriented systems It is a great source of productivity in which some of the ways to implement it could provide and anchor for software code exploits.
Meanwhile, we have Flyweight, Prototype, and Singleton patterns seem to be good solutions for the middle level of an overall API hierarchy. Systems structured this way have a public interface and an implementation core. The implementation may be specified as inaccessible or functionally encoded in such a way as to be fully encapsulated by the public interface. Patterns relevant to implementation as opposed to cross application representation or top-level function may also provide tools to improve performance. They are patterns that may contribute to better runtime efficiency or reduced memory footprint.
The Game Loop pattern is described in good detail in section 3. I see similarities between the description of this pattern and the Iterator pattern from the original 1994 Design Patterns book. While the Iterator pattern, which is one of the most powerful abstract concepts you can ever apply in computer program, is very general in how it is described, the Game Loop pattern is very specific. You could “discover” the Iterator pattern during the course of growing experience in writing software. You really do not need to do that though because the Iterator pattern exists in a permanent, optimized form in the C++ STL and similar libraries. The Game Loop pattern may be less widely known outside of simulation solutions. The use case for it is to gain greater granularity in how you render graphics and manage the overall visual life cycle of a graphical interactive solution. As the author notes, you have a visual loop whenever you use a platform specific application windowing toolkit; a game engine; or other such tool that maps visual output and events on those visuals to an application. The value of knowing the Game Loop pattern in terms of how the author describes it is to gain greater insight into who visual application platforms function. Such knowledge can benefit persons who want to better tailor the operational profile of their solutions to the constraints of such pattern.
A few of the patterns discussed in section 3 such as the Double Buffer and Update Method patterns show great promise in terms of the design of software. I can see a case in which the confluence of State, Double Buffer, and Update Method patterns could prove useful in systems with a higher incidence of concurrency. Even if you do not use the patterns in combination, the analysis expressed in the description of these patterns can perhaps improve one’s perspective in devising more reliable solutions in terms of concurrency and consistent design.
I sense a great deal of value from this book. It reminds me of Steve McConnell’s Code Complete in terms of the wealth of practically useful insights and suggestions in formulating code. I do disagree with some of the descriptions put forward in terms of nomenclature in the titular designations of patterns but that may have to do with the tension between introducing a generalized concept but then clarifying it with a discussion of a concrete nature. Such emphasis on details may erode the generalized tenor of the concept that has gone from concept to practice. I still find the approach useful in terms of those details.
The book does resemble the classic 1994 Design Patterns book in some ways but in other ways it may depart further from the inspirational source. The section on the Update Method pattern may be such a case. However, rather than attempt to address these patterns as elevated ideals fully independent of reality, the patterns described are closer to home. They are patterns that the software development community are likely to produce and encode into software if only by other names. Those who code may not always call functions that do the work of the Update Method by the name update. Regardless, the approach specified in the Update Method pattern is what many are inclined to do as code matures.
The presentation of patterns such as the Update Method pattern is a chance to recognize some patterns in the book for what they are. They are not so much the abstract patterns in a vacuum. They are the patterns of coding from the real world. It is how people code at a certain level of experience and refinement. The book represents a chance to identify good code structure and approach of a consistent nature. That is the chief value of Robert Nystrom’s work in Game Programming Patterns. It is the primary reason more people who write code should read it. The book does talk about these things in the context of simulation technology, but the thoughts expressed are applicable to other areas such as enterprise software and a majority of technology solution in which effective code performance or code structure designs are beneficial.
You can spend considerable time chasing down an appropriate taxonomy for a code base. The names you give things in software and technology matters tremendously. Names are not a trivial matter. Truth, identity, form, and purpose that contributes or detracts from the cognitive contiguity possible when one engages with and operates information systems is influenced by names. Names therefore are a user interface of a different order that affects system usability, adaptability, obviousness, and potential likely hood of reuse and integration with other systems and future internal sub system components. Textual attributions precede design and follows from it at the same time. A book like this has given me an opportunity to pause and consider the author’s suggestion of what are appropriate designations for concepts encoded in software. Everyone who read Robert Nystrom’s book has that same opportunity to accept or reject the descriptions he presents as those who read the 1994 Design Patterns work from the Gang of Four.
As an example, take the Update Method pattern. It could easily be represented by functions with names beside update. Names such as execute, change, revise, and post comes to mind. I have used them all and more but this book can be a reference in which to say a method is termed update for the reasons given in Robert’s description. That, in turn could aid productivity in formulating systems design. It is still just a suggestion however and there are equally excellent reasons to use other designations for the same concept.
The author states that the combination of the Update Method, Game Loop, and Component patterns often forms the core of many games’ operational foundation. I think I can agree with that. The Component pattern, depending on how you apply it may go against data type design suggestions I have read elsewhere. The author lightly introduced the Component pattern a page or so before concluding the discussion on the Update Method pattern. You could potentially merge a field of an enumerated type with an implementation of the Component pattern and a few other revisions to achieve not just inheritance by composition as recommended by the Gang of Four but derive some of the benefits of polymorphism absent virtual method dispatch. I do not know that for sure, but the more I am reading, the more I see another use of this material in aiding focused consideration of design alternatives.