Interestingly, we have been hiring some programmers in the past year, growing the team from just me to five full-time programmers next March. Although the two programmers who have already been working with us for the past year (Ted and Maarten) are former interns of mine, it turned out that as soon as we hired them as real employees, they actually had Opinions. Which is great, because not just blindly doing what I come up with greatly helps against tunnel visions!
One important thing I learned that way recently, is that resetting and reusing objects is error prone, and that a structural change can avoid this.
Let me explain this through an example. In Ronimo's Secret New Game (tm), the player can control a character that when killed, will respawn after a while. My method for doing this, was to hide the character on death, and then reset him when he is respawned, and make him visible again so that the player can continue playing with him.

The problem with this is, that it is easy for the programmer to forget some elements when hiding and resetting. The character consists of many graphical elements, and since they are in very different categories (like healthbar, shadow, character, special effects, etc.), it is not feasible to put all of them in a single list. So when programming the hiding, I need to think of all these elements. The same kind of issue occurs when resetting: many aspects need to be reset (like combo counters, cooldowns on actions, poison time remaining, etc.), and again I need to think of all of them when resetting.
Adding new features is even worse: I always need to remember to add them to the hiding function and to the resetting function. Forgetting one of them results in a bug. Not hiding something is an easy bug to spot, but not resetting something is a lot more difficult to notice, since many effects may usually time out before the respawn timer is over. So it is easy to overlook that sometimes a cooldown may not have expired yet when the player respawns.
This may seem like a subtle and irrelevant issue, but it is very easy to accidentally introduce bugs here when developing a game with more then one programmer, since not everyone may know about these details. So I had been struggling with this for a while, without being able to think of a good solution.
Recenlty, my colleague Maarten came up with a really simple fix: why not completely delete the character on death, and re-create him on respawn? Now we don't need to hide or reset anything. Win!

It turns out that this simple principle actually applies to a lot of things. For example, in Swords & Soldiers, we create all the menus when the game starts, and then just hide them all, except for the one that is currently in view. But why not simply delete them entirely?
Kind of strange that I hadn't thought of this myself, really!
Experienced C++ programmers may counter this argument by saying that dynamic memory allocation costs performance, so resetting is more efficient. This is probably true in most cases. However, I consider design that prohibits bugs to be a lot more important than performance. Current console hardware is very fast and we are not trying to make the next Killzone or Uncharted here.
Anyway, this could also be implemented using placement new (which constructs objects on a piece of memory that you allocated before, instead of requesting new memory). Finally, we have a really fast custom memory manager at Ronimo, so small allocations (up to 256 bytes) are very fast anyway.
Although I didn't think of this re-creation trick myself, it very much fits the coding style at Ronimo: we always try to find structures that make it as difficult as possible to accidentally introduce bugs. Destroying and re-creating objects instead of resetting and reusing them is a great example of this philosophy! Although this example is no super-complex science, I think that one of the most important skills for any programmer is to constantly look at your own code for these kinds of small improvements.