So, in case you haven’t visited before I’m writing a small game using a simple and very effective methodology. I’m also taking you, dear reader, along for the ride!
In our last post (Step 4: In which we transform big software problems into smaller, more manageable ones) we used System Analysis (one of our Analysis Superpowers) to turn our use case diagram and feature list into a set of well encapsulated packages (or systems). Now all we need to do is decide which system we should start on first!
This seems like it should be an easy decision, but don’t be mislead! Where you start your low level design makes a big difference. A lot of engineers (myself included) like to start by working on parts of a solution they already understand; solving problems you already “get” is fast, feels good, and has the fringe benefit of making you look like a total-rock-star. The problem here is starting with what you know well will cause your design to change as you learn about those things you don’t know so well. This can land you in an endless cycle of re-design/re-implementation that could not only tarnish your rock-star image, but might leave your team (even if it’s a team of one) doing twice the work. I know, right? Yikes, indeed. To make sure we avoid anything like that let’s cover our 3rd Analysis Superpower:
Analysis Superpower 003: Building a tower of things you should be worried about!
So, when you see buildings go up in real life – you generally don’t see the construction crew start at the top of the tower and work their way down, I mean, it’s just not done (at least I don’t think it is). In fact, if your building doesn’t have a foundation, or you realize you need to add one later you’re more/less screwed. Which makes foundations one thing you definitely want to think about when you’re building something. Software works the same way – except figuring out just what that foundation should be is occasionally harder than you would think.
One great way to figure out what a foundation should be is to evaluate each system and determine how much risk it poses to the rest of the application. We do this using a little Risk Analysis – which is the process of determining what your foundation is, and which systems build upon it. Good risk analysis can help define interfaces between systems that are much less likely to break over time, and interfaces that don’t break means well encapsulated code that doesn’t need to be re-factored every time a behavior changes.
Have you ever worked on a project with some jerk that breaks all your code because they realized their interface wasn’t going to do the job they wanted it to do? Did they do it multiple times during the process? There are few things I find to be a bigger waste of time than refactoring a ton of code because someone didn’t even try to think it through the first time around.
How not to do risk analysis:
For a project this small figuring this out is kind of a freebie; but it’s still an important part of OOAD. When I’m making a game my knee jerk reaction is to avoid the game engine component. Game engines are huge and require a lot of research and thought, which can seem a little overwhelming. I’ve written some before, and moreover we’re using Unity3d – so let’s see what happens if I just leave that until last and follow my “gut feelings” for what I should work on first:
The problem here is that if my impulsive decisions didn’t work out (and they wouldn’t, because I’m writing it this way on purpose) I’ll have to constantly change my design and rework code as parts about our software that weren’t well understood are exposed – which is a huge waste of everyones time (even if you’re just working by yourself). If you build off of a foundation of the riskiest, least understood systems this kind of refactoring should be kept to a minimum. Now, let’s take a look at a better way to select a foundation…
A better way to do risk analysis:
As you can see I’ve got my systems listed on the left side of the diagram, and my “Tower of things I should be worried about” on the right. Building a tower is a great way to double check your thinking, and it gets you thinking about the lower level relationships of the solution. In order to determine what goes where; each system is given points based on three separate categories, the more points a system has the closer to the foundation it should be. Here’s how the points break down:
- Understanding: Each system is given 1 to 3 poitns based on how well you understand the problem it’s going to solve. 1 point for a well understood system, 3 points for a complete unknown, and 2 points for somewhere in-between.
- Affected by: Each system gets one point for each arrow you can draw pointing away from it (this defines interaction with other systems, events, method calls, etc.).
- Affects others: Each system gets one point for each arrow pointing toward it (this indicates that changes in the interface to this system have the potential to negatively impact other systems).
So, when we total the points I gave each system (they’ll be a little different for everyone) we end up with the Game Engine system at the bottom. The one system I wanted to skip until the end looks like it could’ve caused me more headaches than any of the others. So even though this kind of step seems trivial, it’s always worthwhile to double check your thinking! The very worst thing that could happen is that you find out you were right all along (for me, this is rarely the case). I’ve added what we did today to our Woebot Chapter 1: Design Document, please feel free to review it.
So, that’s it for this post. Next time in Step 6: In which we write use cases that are more fun than a root canal we’ll cover our fourth (and most powerful) Analysis Superpower. Thanks for reading, and please leave and questions or comments you might have down below.