This post is part of a series of reviews on the book Head First: Object Oriented Analysis and Design. Check out the Introduction post for a full table of contents along with some initial notes.
Until now we have been dealing with small problems, which could be solved with no more than 10 classes each, but real applications go way past that, this time we’re gonna be solving a really big problem. Since this chapter is all theory, there’s no project on GitHub for it, but be sure to read this if you’re going to read the next chapters, because this will be the baseline for all our work to come.
The key to solving big problems is simply treating them as a bunch of small problems, taking one at a time and using the three steps to ‘great software’ we’ve been using so far on them. Let’s review some topics we’ve been through just to freshen up:
- Encapsulate what varies to make your application more flexible and easier to change.
- Understand what the system has to do to gather good requirements.
- Code to an interface rather than coding to an implementation, making your software easier to extend.
- Great software is easy to change and extend, also doing what the customer wants it to.
- Analysis helps you ensure your system works in a real-world context.
Alright, now that we got the concepts reviewed, let’s take a look at the big problem we’ll be solving (this will be directly copied from the book, with some cosmetic changes):
Game System Framework (GSF)
This system will provide a framework that game designers can use to create turn-based strategy games. Unlike arcade-style shoot-’em-up games and games that rely on audio and video features to engage the player, our games will focus on thge technical details of strategy and tactics. Our framework provides the bookkeeping details to make building a particular game easy, while removing the burden of coding repetitive tasks from the game design.
This framework will provide standard capabilities for:
- Defining and representing a board configuration
- Defining toops and configuring armies or other fighting units
- Moving units on the board
- Determining legal moves
- Conducting battles
- Providing unit information
This framework will simplify the task of developing a turn-based strategic board game so that the users of this framework can devote their time to implementing the actual games.
Lots of talk, not so much useful info to write requirements or use cases. That’s what you will get most of the times. We need to talk a little bit more with our customer and write down things such as what is the system like (commonality) and what the system is not like (variability). When you talk to customers you will likely be fed features, which is just a high-level description of something a system needs to do, and with those features we can figure out the requirements you need to implement those features.
Now, the book shows a huge conversation between company characters (that we’re supposed to pay attetion to), and since I’m not gonna write that whole thing down, let’s just see the useful part of it, these are the features our customers supplied:
- Supports different types of terrain.
- Supports multiple types of troops or units that are game-specific.
- Each game has a board, made up of square tiles, each with a terrain type.
- Supports different time periods, including fictional periods like sci-fi and fantasy.
- Supports add-on modules for additional campaigns or battle scenarios.
- The frameworks keeps up with whose turn it is and coordinates basic movement
Now that’s something to work with! But before we choose a functionality to start writing requirements and use cases on, it’s good to always have a notion of the big picture in your head, so you don’t trail off on what you’re really supposed to do. To help us with the big picture dilemma we’ll be using another type of UML drawing (ugh) called use case diagrams.
Use case diagrams are useful when you need to know what a system does but don’t want to get into all the detail that use cases require. With that said, let’s draw a use case diagram for our framework:
The grey box represents the system, the ovals represent each use case in the system and the little guy represents the system’s actors (people who will interact with the system). In that diagram we only put the basic stuff, “but what about all the features?” you ask, exactly, let’s now use our feature list to make sure our use case diagram is complete.
We can throw the first five features into the first use case “Create New Game” or “Modify Existing Game” (in case of a redesign), but what about the last one? It simply doesn’t fit anywhere, which is a problem. If our features don’t all fit in our use case, then that means we’re missing something. Wait a minute, we’re developing a game framework, right? Which means that we’re not developing the game itself, but the foundations for it, so, every game developed will be interacting with our framework, which leads us to the solution of our problem: the game is also an actor! Let’s redraw our use case diagram adding that new actor to it along with all the things that the game uses the framework for:
Note: The DIA export bugged, that’s Take Turns and Add/Remove Units
Cool, now we have a global idea of what our system has to do, kind of like a blueprint of our application.
I said in the beggining of the review that the best way to solve a big problem is to divide it into smaller problems and tackle one at a time. So, using our features and our use case diagram, we can split our framework into modules that will handle a group of funcionalities. Remember, the game has to handle terrain, time periods, units and tiles, along with keeping track of movement and whose turn it is. There’s alot of ways to break this up, but the book suggests this solution:
- Units – Takes care of all game units used in the game, such as troops.
- Board – Handles tiles and terrain types by creating an actual game board.
- Game – Will store basic classes related to time period and other basic properties that can be extended by designers.
- Utilities – For tools and helper classes used across modules.
- Controller – Used to keep track of the whole game, including movement and turns, this module will be the application’s brains.
We could also include a Graphics module that would be used to deal with any interface, but that’s a job for a game designer. Notice how we could use a design pattern called MVC (Model-View-Controller), the same one used in Ruby On Rails, where Board and Units would be our models, Controller would be our controller and Graphics would be our view (Game and Utilities don’t really fit). Don’t worry if you don’t know much about MVC though, it’s just a side note.
Alright! We turned a big problem into a bunch of little problems that can be totally dealt with and we have our blueprint to always check on, so now it’s time to work on those smaller problems. On the next chapter :)