138 Chapter 10 ■ Data structure design The main reference on this method is: M.J. Jackson, Principles of Program Design, Academic Press, 1997. Read all about the many serial file formats in mainstream use in: Gunter Born, The File Formats Handbook, International Thomson Publishing, 1995. Answers to self-test questions 10.1 A new line is needed for each occurrence of process line. 10.2 Record Male Not male * Further reading • BELL_C10.QXD 1/30/05 4:22 PM Page 138 We begin this chapter by reviewing the distinctive features and principles of object- oriented programming (OOP). This sets the scene as to what an OOD seeks to exploit. Then we look at how to go about designing software. We use the Cyberspace Invaders game as the case study. The widely agreed principles of OOP are: ■ encapsulation ■ inheritance ■ polymorphism. The advantages of these features is that they promote the reusability of software com- ponents. Encapsulation allows a class to be reused without knowing how it works – thus modularity and abstraction are provided. Inheritance allows a class to be reused by using some of the existing facilities, while adding new facilities in a secure manner. Polymorphism further promotes encapsulation by allowing general purpose classes to be written that will work successfully with many different types of object. Object-oriented languages are usually accompanied by a large and comprehensive library of classes. Members of such a library can either be used directly or reused by employing inheritance. Thus the process of programming involves using existing library classes, extending the library classes, and designing brand-new classes. During OOD, the designer must be aware of the wealth of useful classes available in the libraries. To ignore them would be to risk wasting massive design, programming 11.1 ● Introduction CHAPTER 11 Object-oriented design This chapter: ■ explains how to carry out object-oriented design (OOD) ■ explains how to use class–responsibility–collaborator (CRC) cards ■ emphasizes the importance of using ready-made libraries. BELL_C11.QXD 1/30/05 4:22 PM Page 139 140 Chapter 11 ■ Object-oriented design and testing time. It is common experience for someone setting out to write OO soft- ware to find that nearly all of the software already exists within the library. OO de- velopment is therefore often regarded as (merely) extending library classes. This, of course, requires a discipline – the initial investment in the time to explore and learn about what might be a large library, set against the benefits that accrue later. One of the principles used in the design of object-oriented software is to simulate real world situations as objects. You build a software model of things in the real world. Here are some examples: ■ if we are developing an office information system, we set out to simulate users, mail, shared documents and files ■ in a factory automation system, we set out to simulate the different machines, queues of work, orders, and deliveries. The approach is to identify the objects in the problem to be addressed and to model them as objects in the software. One way to carry out OOD is to examine the software specification in order to extract information about the objects and methods. The approach to identifying objects and methods is: 1. look for nouns (things) in the specification – these are the objects 2. look for verbs (doing words) in the specification – these are the methods Here is the specification for the cyberspace invaders program: A panel (Figure 11.1) displays a defender and an alien. The alien moves sideways. When it hits a wall, it reverses its direction. The alien randomly launches a bomb that moves vertically downwards. If a bomb hits the defender, the user loses and the game is over. The defender moves left or right according to mouse movements. When the mouse is clicked, the defender launches a laser that moves upwards. If a laser hits the alien, the user wins and the game is over. A button is provided to start a new game. Scanning through the specification, we find the following nouns. As we might expect, some of these nouns are mentioned more than once, but the repetition does not matter for the purpose of design. panel, defender, alien, wall, bomb, mouse, laser These nouns correspond to potential objects, and therefore classes within the pro- gram. So we translate these nouns into the names of classes in the model. The noun panel translates into the Panel class, available in the library. The nouns defender and alien translate into the classes Defender and Alien respectively. The noun wall 11.2 ● Design BELL_C11.QXD 1/30/05 4:22 PM Page 140 11.2 Design 141 need not be implemented as a class because it can be simply accommodated as a detail within the class Alien. The noun bomb translates into class Bomb. The noun mouse need not be a class because mouse click events can be simply handled by the Panel class or the Defender class. Finally we need a class Laser. Thus we arrive at the following list of non-library classes: Game, Defender, Alien, Laser, Bomb These are shown in the class diagram (Figure 11.2). This states that the class Game uses the classes Defender, Alien, Laser and Bomb. We have not yet quite completed our search for objects in the program. In order that collisions can be detected, objects need to know where other objects are and how big they are. Therefore, implicit in the specification are the ideas of the position and size of each object. These are the x and y coordinates, height and width of each object. Although these are potentially objects, they can instead be simply implemented as int variables within classes Defender, Alien, Laser and Bomb. These can be accessed via methods named getX, getY, getHeight and getWidth. One object that we have so far ignored in the design is a timer from the library that is set to click at small regular time intervals, in order to implement the animation. Whenever the timer ticks, the objects are moved, the panel is cleared and all the objects Figure 11.1 The cyberspace invaders game BELL_C11.QXD 1/30/05 4:22 PM Page 141 142 Chapter 11 ■ Object-oriented design are displayed. Another object is a random number generator, created from the library class Random, to control when the alien launches bombs. We have now identified the classes that make up the game program. We now scan the specification again, this time looking for verbs that we can attach to the above list of objects. We see: display, move, hit, launch, click, win, lose Again, some of these words are mentioned more than once. For example, both the alien and the defender move. Also all the objects in the game need to be displayed. We now allocate methods to classes, with the help of the specification. This con- cludes the design process. Now although we used the specification to arrive at classes and methods, we could have used an alternative formulation of the specification, use cases. Use cases were explained in Chapter 4 on requirements specification. A use case is a simple, natural language statement of a complete and useful function that a system carries out. For the game, some use cases are: ■ defender move – when the user moves the mouse left and right, the defender object moves left and right on the screen ■ fire laser – when the player clicks the mouse, a laser is launched upwards from the defender object ■ laser hits alien – when a laser hits the alien, the player wins and the game is over Notice that some of the use cases are not initiated by the user of the system. Instead they are initiated by objects within the game, such as when an alien launches a bomb. A complete set of use cases constitutes a specification of what a system should do. We can then use them to derive classes and their methods. Again, we seek verbs (which are the classes) and verbs (which are the methods). Fortunately use cases are very suit- ed to this process, because they emphasize actions acting on objects. So, for example, the use case defender move implies that there is an object defender that embodies methods moveLeft and moveRight. Figure 11.2 The non-library classes involved in the game program Defender Alien Laser Bomb Game BELL_C11.QXD 1/30/05 4:22 PM Page 142 11.2 Design 143 While we are identifying classes and methods, we can document each class as a UML class diagram. This type of class diagram shows more detail about a class than those we have met so far. A large rectangle contains three sections. The first section simply shows the class name. The second section shows the instance variables. The third section shows the public methods provided by the class. We start with class Game: SELF-TEST QUESTION 11.1 Derive information about objects and methods from the use case: ■ laser hits alien – when a laser hits the alien, the player wins. class Game Instance variables panel timer Methods mouseMoved mouseClicked actionPerformed class Defender Instance variables x y height width Methods move display getX getY getHeight getWidth Next we consider the defender object. It has a position within the panel and a size. In response to a mouse movement, it moves. It can be displayed. Therefore its class diagram is: BELL_C11.QXD 1/30/05 4:22 PM Page 143 We now have the full list of classes, and the methods and instance variables associated with each class – we have modeled the game and designed a structure for the program. The next act of design is to check to make sure that we are not reinventing the wheel. One of the main benefits of OOP is reuse of software components. At this stage we should check whether: ■ what we need might be in one of the libraries ■ we may have written a class last month that is what we need ■ we may be able to use inheritance. We see in the cyberspace invaders software can make good use of GUI components, such as the panel, available in the library. Other library components that are useful are a timer and a random number generator. If we find classes that are similar, we should think about using inheritance. We look at how to write the code to achieve inheritance in Chapter 15 on OOP. In Chapter 13 on refactoring, we look at identifying inheritance using the “is-a” and “has-a” tests. 11.3 ● Looking for reuse 144 Chapter 11 ■ Object-oriented design Next we design and document the Alien class. The alien has a position and a size. Whenever the clock ticks, it moves. Its direction and speed is controlled by the step size that is used when it moves. It can be created and displayed. Class Alien Instance variables X Y height width xStep Methods Alien move display getX getY getHeight getWidth SELF-TEST QUESTION 11.2 Write the class diagram for the Bomb class. BELL_C11.QXD 1/30/05 4:22 PM Page 144 11.5 Class–responsibility–collaborator cards 145 We shall see how the game software can be considerably simplified by making use of inheritance. OOP is often called programming by extending the library because the libraries pro- vided along with OO languages are so rich and so reusable. An organization will often also create its own library of classes that have been created in earlier projects. There are two distinct ways of using classes in a library: 1. creating objects from classes in the library 2. defining new classes by extending (inheriting from) classes in the library. For example, in designing the game program, we expect the library to provide classes that implement buttons and a panel – along with classes that support the event handling associated with these widgets. For example in the Java library we can use the Button class directly, by creating button objects as instances of the Button class: Button button = new Button("start"); The Java library also provides classes and methods that display the graphical images that the program uses. Another way in which the library is commonly used is to form new classes by inheritance. It is worthwhile looking in the library at the outset of design and then again at every stage of design, in case something useful can be incorporated into the design. This takes some self-discipline because it is tempting to write a method again, rather than develop an understanding of someone else’s code. Class–responsibility–collaborator (CRC) cards are a way of helping to carry out OOD. The technique uses ordinary index cards, made out of cardboard and widely available. Each card describes an individual class as shown by the example of the Alien class in Figure 11.3. The designer begins by writing the class name at the head of the card. Then one area lists the methods provided by the class (its responsibilities). For the class Alien, these are move, display, etc. A second area lists the classes that use this class and the classes that are used by this class (the collaborators). For the class Alien, there is only one, the library class Graphics that supports displaying graphical images. The cards representing the constituent classes are placed on a table. This way the cards can be moved around easily; their interrelationships can be visualized and adjust- ed as necessary. CRC cards offer advantages as compared with a software tool. They are cheap, read- ily available and portable. Several people can easily collaborate, standing round the 11.5 ● Class–responsibility–collaborator cards 11.4 ● Using the library BELL_C11.QXD 1/30/05 4:22 PM Page 145 table. It seems that the act of physically handling the cards contributes to an improved understanding of the structure of the software. Iteration is a crucial ingredient of OOD. This is because there is no guaranteed for- mula for finding the right set of objects to model a problem. Therefore the process is exploratory and iterative; it is common for classes to be initially proposed during a design but subsequently be discarded as the design progresses. Similarly, the need for some classes will not emerge until the implementation (coding) stage. During each iteration, the design is refined and reanalyzed continuously. Indeed, whereas design and implementation are considered largely distinct activities in tradition- al software development, using the object-oriented paradigm the two activities are often indistinguishable. There are a number of reasons for this, which we will now discuss: Prototyping is seen as an integral part of the object-oriented software design and imple- mentation process. Prototyping recognizes that in most cases the requirements for a sys- tem are at best vague or not well understood. It is an exploratory process providing early validation (or otherwise) of analysis, design and user interface alternatives. Prototyping dic- tates that design and implementation proceed in at least large-grain iterative steps. The activities which take place and the concerns which are addressed during the refinement of an OOD are identical whether it is the design or a working prototype that is being refined. Moreover, such activities as reorganizing the class to reflect some newly recognized abstraction (see Chapter 13 on refactoring) are just as likely to take place during the implementation of a prototype as during the design. The design must now be updated to reflect this change – design and implementation are now proceeding in small-grain iterative steps. Designers must be far more aware of the implementation environment because of the impact that a large reusable class library can have on a design. Designers must not only be aware of the library classes but also design patterns (see Chapter 12). To sum up, as noted by Meyer, one of the gurus of object-oriented development, designing is programming and programming is designing. 11.6 ● Iteration 146 Chapter 11 ■ Object-oriented design Class name: Alien Responsibilities Collaborators moves Graphics displays itself provides its x coordinate provides its y coordinate provides its height provides its width Figure 11.3 A Sample CRC card – the class Alien in the cyberspace invaders game BELL_C11.QXD 1/30/05 4:22 PM Page 146 Summary 147 OOD and OOP have become the dominant approach to software development. This is assisted by the availability and widespread use of programming languages that fully sup- port OOP – such languages as C++, Ada, Smalltalk, C#, Visual Basic.Net and Java. A number of OOD methodologies have appeared and are used. The available methodologies differ in: ■ their degree of formality ■ which features of the problem they choose to model (and not model) ■ the types of application for which they tend to be most suited (e.g. information sys- tems versus real-time control systems). The strengths of the object-oriented approach are: ■ the intuitive appeal of directly modeling the application as objects, classes and methods ■ the high modularity (information hiding) provided by the object and class concepts ■ the ease of reuse of software components (classes) using inheritance. Note that OOD leads to structures that are non-hierarchical, which distinguishes it from some approaches. 11.7 ● Discussion Summary OOD can be characterized as a three-stage process: 1. find the classes, i.e. determine the objects involved and their classes 2. specify what the classes are responsible for, i.e. what they do (their methods) 3. specify their collaborators, i.e. other classes they need to get their jobs done. The following techniques and notations can be used for design: ■ identify nouns and verbs in the specification or the use cases to derive classes and methods ■ use the library – at every stage during design it is worthwhile looking in the library for classes that can either be used directly or extended by inheritance ■ use CRC cards – a means of establishing the responsibilities (methods provid- ed) and collaborator classes of each of the classes. BELL_C11.QXD 1/30/05 4:22 PM Page 147 . advantages as compared with a software tool. They are cheap, read- ily available and portable. Several people can easily collaborate, standing round the 11.5 ● Class–responsibility–collaborator. the availability and widespread use of programming languages that fully sup- port OOP – such languages as C++, Ada, Smalltalk, C#, Visual Basic.Net and Java. A number of OOD methodologies have appeared. identifying classes and methods, we can document each class as a UML class diagram. This type of class diagram shows more detail about a class than those we have met so far. A large rectangle contains