Building a Hierarchy: Steps in OOP Design

   

When setting out to develop an OOP program for the first time, it is often helpful to have an ordered set of steps to follow. Developing good OOP structures is like most work that you do in that the outcome is largely determined by the analysis of the problem that you do before attempting a solution. In the case of OOP, the goal here is to first decide what classes and objects are required to support a program before doing any coding. This section introduces several steps to guide you through that process.

Decompose the Problem into Entities

When writing an OOP program, it's first necessary to figure out the types of objects that are needed. As an example, if you were writing an adventure video game, you would need to figure out everything in that game, such as the main character, the opponents to battle, power pieces to adjust the abilities of the main character, ammunition, and so on. A common approach to creating such a list is to write out a description of what a program must do, and look for the nouns that appear in that description. For example, part of a description of a video game might state, "The user controls the movement of the main character, who can pick up ammunition and use that ammunition to inflict damage on one or more opponents." When you use this approach, every noun that you find is not a part of the problem domain that needs to be represented in your program, but those nouns that appear often and are involved in key actions are definitely the candidates to consider.

After you have identified the significant parts of the problem domain, you need to break them down into individual entities, both data and functional. For this example, you might create a list like this for the four items:

Game Part Data and Functional Needs
Main Character Capability to receive commands from the user; capability to move around the maze according to these commands; attack capability; location; power level; and size
Opponents Location; size; power level; attack capability; and maneuverability
Power Pieces Appearance when drawn; location; and power level
Ammunition Capability to be fired ; damage level; and quantity

Look for Commonality Between Entities

A strength of OOP is the exploitation of common behavior to achieve code reuse. After the entities required by a program have been identified, a frequent next step is to look for common characteristics across entities. Perhaps the most obvious commonality in this example is an easy one to overlook at first: the capability for each entity to be drawn on the screen. This capability is so obvious you might just miss it. Remember to consider low-level functionality that might be considered obvious, because it often carries a big payback in reduced development time.

The game entities also have higher-level characteristics in common. From the data and functional needs identified in the list of game parts, you can see that the main character, the opponents, and the power pieces all have a location. It is also true that the main character and the opponents have a size, a power level, and an attack capability. You can quickly see here that significant code reuse could be achieved by writing the code to control attributes such as location, power, and size once, and then sharing that code through inheritance.

Look for Differences Between Entities

Making sure that you uncover the areas that truly differentiate entities is equally as important as identifying commonality. For this program, one example of a key difference is that the power pieces remain in a fixed location until consumed, but a piece of ammunition moves after it is fired toward the main character or an opponent . When performing this exercise, you are looking for qualities and behavior that either unite or separate entities in your program.

Significant to note here is that the primary difference between the main character and the opponents within the game (aside from how they look) is who controls each. Namely, the computer controls the opponents, and the user controls the main character. It would be a great advantage if you could write most of the code for both the opponents and the main character once, and then write only the code that moves them separately. Treating objects this way is exactly what the OOP paradigm is all about.

Design a Hierarchy Using Abstraction and Inheritance

The point of identifying entity commonality and differences is to use it to define a class hierarchy. One approach to this is to start by focusing on the greatest common characteristic across the entities in your program. Looking at the game example, what do you see that all four objects have in common? A quick list might include, at a minimum, size and location attributes. Also, remember that the low-level requirement to be drawn on the screen is shared by every entity.

With these entities, you could create a class called DrawnObject to take advantage of the commonality identified. This class would contain the attributes and behavior related to size, location, and the common screen drawing requirements.

The next step is to continue to group objects that still have common characteristics together (after you have eliminated the aspects that were just grouped into the previous class). You can use these commonalties to produce another level of classes, each of which inherits from DrawnObject to take advantage of the highest level of commonality.

Going back to the example, at this point the power pieces and the ammunition probably split from the opponents and the main character because they have nothing in common beyond what can be captured in DrawnObject. You can now take the remaining objects and repeat the steps of the design procedure again.

Going through the next iteration, you find that the only real difference between the power pieces and the ammunition is their size and how fast they move (the power pieces at speed 0). Even though these are primarily minor differences, you could choose to create a Powerup class to define the shared behavior and inherit Ammunition and PowerPiece classes from it to address the differences.

When you look at the opponents and the main character, you see that they are not the same, but they do have much in common. Here you can define a GameCharacter class to hold the shared attributes and behavior and inherit Opponent and MainCharacter classes from it. The major difference between Opponent and MainCharacter would be in the control of entity movement.

The resulting class hierarchy from this approach is shown in Figure 1.1. Try this process on your own. There are countless variations to the design developed here that depend on how the various tradeoffs are addressed.

Figure 1.1. Building a class hierarchy for your game enables you to save a lot of coding.

graphics/01fig01.gif

   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net