Identifying Object Behaviors (or Methods)

Objects do not only have attributes; they also have behaviors. Our programs ask an object to act out its behaviors by using methods. A method is very much like a subprogram, or function, that our program can call; but whereas a subprogram is simply a routine in our program, a method is a routine defined for our object.

Objects have behaviors that help model their role in business process. Very often, they also have behaviors, or methods, that let them interact with the other objects in the model - in ways that aren't necessarily obvious from the use cases.

We're going to discuss business process behaviors in this section. We'll cover object relationship behaviors in the next section.

The technique we need to follow to determine an object's behavior is very similar to that which we've just seen for an object's properties. First, we need to go through the functional use case to find any methods that are required. Then, we need to look at our object model and add any methods that are required for objects to interact with each other.

Identifying Behaviors - Looking through the Use Case

Let's look through each object in our object model and read through the use case to decide what behaviors or actions each object might be able to take. Many business objects primarily provide data, so don't be surprised if many of our objects don't have methods.

Looking at the customer object, we can see that the actual person does a lot of things, like putting the videos on the counter, and providing an ID card. However, our software doesn't need to be aware of these actions - so we don't need to provide methods for them. But our software does need to retrieve and display the customer's name and address once the ID number is entered. Now, since these are attributes of the customer object, it's a good bet that our customer object will have some behavior to load this information.

Next, let's look at the video object. Again, the video object doesn't play an active part in the use case as far as our application is concerned - other than that it needs to load the description and rental price once its ID number is entered.

Our last object is the invoice object. This object isn't directly in the use case at all, but it does have the subtotal, tax and total values as attributes. The use case indicates that these values are calculated, so the invoice object will probably need a method to support this behavior.

At this point, our objects have the following behaviors:

Object Behavior
Customer Load customer data
Video Load video data
Invoice Calculate subtotal

Calculate tax

Calculate total


If we look back at the requirements use case, we can see that there are other behaviors that we are not taking into account. For instance, the invoice needs to be printed, and it is implied that the rented videos will be recorded in the inventory system. We don't need to worry about these issues at this point, since they would normally be covered by other functional use cases. This illustrates how closely all the different use cases are related to each other, and how they are all used together to come up with a comprehensive object model.

Identifying Behaviors - Looking through the Object Model

The customer and video objects both have behaviors that comprise loading data from a database. This type of behavior is integral in making objects persistent, as we discussed in Chapter 2. In Chapter 4, we'll get into the code for implementing this behavior. For now, however, we're just interested in defining our objects' interfaces, so we'll add a Load method to support this behavior, and worry about the details later.

We've listed three different calculation behaviors for the invoice object, all of which are closely related. This is an interesting situation that requires some thought. There are three ways to approach these behaviors:

When we're making decisions about our objects' interfaces, we need to keep our customer in mind. We have two main design issues: modeling the business entities, and making our objects easy to use at the presentation layer. Here, our customer is the programmer who is writing the user interface.

Implementing three different calculation methods means that the UI programmer needs to understand and call all three methods where appropriate. Since all the calculations are directly tied to each other, it would surely be much better to combine them into a single method for the programmer to call.

Better still, suppose the programmer didn't need to call any method to do the calculation. The calculation would only need to happen when a video was added or removed from the list of rentals. The invoice object owns the list of videos, so it should be able to detect when a video is added or removed - and automatically recalculate the values.

All three solutions are valid, and we could choose any of them and have a working program. We should always strive to provide the simplest object interface for the UI programmer, since it helps them to be more productive and it makes the code less prone to bugs. In this case, the upshot is that we'll opt to automatically recalculate the subtotal, tax and total, so that those values are always correct. This means we don't need any calculation methods on our invoice object.

Ideally, we'd be able to notify the UI when the values have been recalculated, thus making it easy for the programmer to update the display. Fortunately, Visual Basic 5.0 provides the RaiseEvent command to let us do just that.