I just skimmed through a Gamasutra article titled Game Coding Complete: Smart Design Practices (a book excerpt from an O'Reilly title) which lists a few practical tips for covering your ass codewise. Coming from the game development world, some of the practices are a bit irrelevant for the typical modern day business application developer doing J2EE but some of them hold equally well both sides of the chasm.
Avoid hidden code that performs nontrivial operations
The first practice is what I consider to be of high importance. The principle of least surprise is an important one and we should remember to keep that in mind when pounding away in our IDE's. Encapsulation is a good thing if done right but it can be misused for hiding details that the client code (or its author) really should be informed about. The obvious example is a getter method that one assumes to be a dirt-cheap operation while it's really hitting the database on every call. However, it's not about the performance -- it's about us knowing what our code is doing.
Keep your class hierarchies as flat as possible
Earlier today, a discussion passed the subject of frameworks that require one to extend a base class (examples include JUnit and Struts, among others) and how that's a smell, regardless of whether this restriction is a conscious design decision or a necessity dictated by the constraints of the technology in use. The fewer levels of inheritance in your system, the easier it is to understand--and evolve.
Be aware of the difference between inheritance and containment
Related to the previous point, it is important to realize when inheritance really is appropriate. In fact, I'd say that most of the time it's not! Aggregation has long proven to be much more flexible than inheritance. Inheritance is a good tool. It's just not for nails of all sizes.
Avoid abusing virtual functions
While virtual functions are not an issue for Java developers, the underlying theme of avoiding situations where bad things can happen is not to be dismissed lightly, either. Using the very latest features of the very latest technology or programming language might not be the best choice for the project or the company. "Right tool for the job" should not exclude the fact that there's people involved in software development, believe it or not. Thinking about your "audience" is hardly ever a bad idea...
Use interface classes and factories
'Nuff said. Abstraction is a powerful technique. Provided that we don't abuse it, that is. I've recently been subjected to a relatively big codebase on a portal project. Beyond the usual procedural-code-written-in-Java terror, I've come to realize that one of the major obstacles for getting new people up to speed quickly is that the system is missing at least one layer of abstraction between the application code and the underlying portal product's API.
Use streams in addition to constructors to initialize objects
This last one is very much game development specific so I don't have much to say about it. It makes sense, but I must say I don't quite see why McShaffry included this particular practice among the others. It's almost like he's mixing two levels of abstraction here ;)
I spotted a great piece of information from a link in Mike Clark's post on the ActiveRecord library used in Rails.
That piece of information was an article at SitePoint.com about something called modified preorder tree traversal. It's essentially a fast algorithm for query operations on a hierarchical set of data stored in a relational database -- a problem we usually tackle with an adjacency list, i.e. tacking a "parent_id" column on each record and perform a series of database queries in order to fetch a (sub)tree of records.
The modified preorder tree traversal algorithm is a funky one. I won't explain it in detail here (go read the SitePoint article for an excellent description!) but it's basically a way to structure your hierarchical data in a relational database in a way that let's you fetch an arbitrary subtree from the database using just two (2) SQL queries. The first one is for fetching details for the root node of the subtree and the second one is to fetch all the children and grandchildren of the root node.
The trade-off is two-fold:
1) This solution is less intuitive than the adjacency list approach because of its algorithmic flavour
2) This solution makes updating/deleting/inserting records a bit expensive because we need to update the index (the index is what makes the SELECT operations lightning fast)
Check it out if you haven't heard of it already. I have to admit that I've never been good at algorithms nor specifically interested in them. Yet, I'm excited to learn new ones that are actually useful!
Thanks, Mike!
Today, just a few hours ago, for the first time in my life, I met someone who writes wikipedia (the Finnish wikipedia to be more accurate).
Meet Joonas:
Well, actually I had met him before but I didn't know he's writing that stuff. Joonas is an ex-colleague, a future colleague, and a very nice guy in general. And he's admitted being seriously addicted to writing the wikipedia. It's something about those red links with a question mark urging for your attention, I guess...
Tim Bacon blogs about retronyms. He also links to Scott Ambler's old article where he turned the four values of the Agile Manifesto around. It's often interesting how "multiplying by -1" can change the perspective of things.
Tim, by the way, is an ex-ThoughtWorker (who in XP2005 mentioned something about big consultancies like Accenture, IBM, EDS and the like being the root of all evil in IT today :) just like Rachel, apparently, who blogs about the combination of an intensive project and long commute eating up a lot of energy.








