Furthering the Object-Oriented Mindset
This is the fifth installment in a series of articles about fundamental object-oriented (OO) concepts. The material presented in these articles is partially excerpted from the second edition of my book, The Object-Oriented Thought Process, 2nd edition. The Object-Oriented Thought Process is intended for anyone who needs to understand the basic object-oriented concepts before jumping into the code.
As we saw in last month's article, one of the first thought process skills you must master is how to actually think in terms of objects. This may be easier than you think because in the real world you do think in terms of objects. It is simply a matter of changing your software development paradigm to think in terms of objects rather than thinking of a program as simply code and data. In this installment, we will further discuss how you start thinking in terms of objects.
Using Abstract Thinking when Designing Interfaces
One of the main advantages of OO programming is that classes can be reused. In general, reusable classes tend to have interfaces that are more abstract than concrete. Concrete interfaces tend to be very specific, whereas abstract interfaces are more general. However, simply stating that a highly abstract interface is more useful than a highly concrete interface, although often true, is not always the case.
It is possible to write a very useful, concrete class that is not at all reusable. This happens all the time, and there is nothing wrong with it in some situations. However, we are now in the design business, and want to take advantage of what OO offers us. So, our goal is to design abstract, highly reusable classes—and to do this we will design highly abstract user interfaces. To illustrate the difference between an abstract and a concrete interface, let's create a taxi object. It is much more useful to have an interface such as "drive me to the airport" than to have separate interfaces such as "turn right," "turn left," "start," "stop," and so on, because as illustrated in Figure 1, all the user wants to do is get to the airport.
Figure 1: An abstract interface.
When you emerge from your hotel, throw your bags into the back seat of the taxi and get in, the cabbie will turn to you and ask, "Where do you want to go?" You reply, "Please take me to the airport." (This assumes, of course, that there is only one major airport in the city. In Chicago you would have to say, "Please take me to Midway Airport" or "Please take me to O'Hare.") You might not even know how to get to the airport yourself, and even if you did, you wouldn't want to have to tell the cabbie when to turn and which direction to turn, as illustrated in Figure 2. How the cabbie implements the actual drive is of no concern to you, the passenger. (Of course, the fare might become an issue at some point, if the cabbie cheats and takes you the long way to the airport.)
Now, where does the connection between abstract and reuse come in? Ask yourself which of these two scenarios is more reusable, the abstract or the not-so-abstract? To put it more simply, which phrase is more reusable: "Take me to the airport," or "Turn right, then right, then left, then left, then left?" Obviously, the first phrase is more reusable. You can use it in any city, whenever you get into a taxi and want to go to the airport. The second phrase will only work in a specific case. Thus, the abstract interface "Take me to the airport" is generally the way to go for a good, reusable OO design, whose implementation would be different in Chicago, New York, or Cleveland.
Figure 2: A not-so-abstract interface.