The interesting things I learned along the way in terms of coding were about when to re-factor towards patterns, a serious lesson in why we should use RAII everywhere and some interesting uses for the Visitor pattern.
After working on projects of varying maturity, I've now seen code bases that are pattern-heavy and those without many pre-formed architectural patterns. If either of these types of code base need modifying - particularly if the modifications are to be structurally significant - then the pattern-heavy architecture is quite resistant and brittle, whereas the pattern-light code base is pliable and less unstable. The lesson I've learned from this is that patterns should come late: try not to create a pattern for single use; wait for the pattern to emerge from multiple client uses; re-factor when you write the same code three times, rather than twice.
I've been a fan of RAII since I learned about it and have come to realise that it's not just an exception safety paradigm. The code I've seen that can most benefit from RAII is many coders' worst nightmare: the OpenGL state machine. GL bugs where colours change, textures disappear, lighting goes wrong and so on are notoriously hard to debug, requiring quite a talent and intuition (which I must admit I don't possess). Why then don't we write a suite of RAII objects for doing glEnable and glDisable and so forth? If we did this, then we're guaranteed to leave the GL state machine in the same state across calls to any draw() function we could ever write. For general setup code, more scene graph-like hierarchies of draw code and nested transformations, we simply use the stack to nest RAII object lifetimes.
My last interesting encounter on our boujou development journey has been the visitor pattern: surprising, because we're taught that this should be a seldom used pattern. Now I'm not talking about the full blown visitor pattern, I'm talking "visitor-lite" whereby a set of visited objects contribute to a visiting class's state via identical, primitive calls (rather than visitA, visitB, visitC and so on). This proves to be immensely useful when the visitor is polymorphic (either literally or by binding different classes and functions to a simple functor). Imagine a selection of entities that can contribute to a context menu, a UI panel or a script engine through exactly the same visitor framework? How about using the same drawing code to render entities in 2D and 3D, find their extents, cache draw lists and fill structures for algorithms?
So, despite the usual ups and downs of a commercial software project, boujou's been a pleasure to work on and it's been good for me. I hope it's good to its users.
Post a Comment