Remember back during your grammar school days when you tried to shape a hunk of modeling clay into your favorite car? No matter how much you poked, pulled, and pounded, the clay never resembled an automobile. And yet designers for auto manufacturers poke, pull, and pound the same clay as you, but are able to transform the hunk of clay into a work of art that eventually drives onto the showroom floor. Auto designers have the know-how to model a real-world automobile out of clay. The same can be said about professional object-oriented programmers. They have the skills to apply object-oriented programming theory to model real-world objects in a program. You ll learn those skills in this chapter.
Experienced object-oriented programmers soon realize after learning their trade that the real world isn t as perfect as the examples used to explain the concepts of object-oriented programming. Somehow the real world cannot always be organized into clearly defined objects that can be represented by classes in an application.
Programmers have to be adept at applying object-oriented programming theory where it makes sense without unnecessarily complicating the coding in an application. They also have to be clever to know when not to use object-oriented programming in an application.
We ll explore the realities of using object-oriented programming to model the real world throughout this chapter and in doing so we ll illustrate common problems and how experienced programmers overcome them.
Some programmers believe the popularity of object-oriented programming was seeded by the development of graphical user interfaces (GUIs) because a GUI is composed of objects such as buttons, radio buttons , list boxes, and other familiar graphics. Each object is encapsulated with data and behaviors.
For example, the push button object encapsulates data such as height, width, color , text, and screen position. It also encapsulates behaviors such as the actions that occur when the cursor is placed over the button, when the cursor moves away from the button, and when the button is clicked.
A GUI screen is built by selecting objects from a toolbox and placing them on the screen. The screen inherits all the data and behaviors of an object. The GUI is one of the successful implementations of object-oriented programming theory because GUI objects fit the object-oriented programming model.
Some programmers feel that object-oriented programming theory must be tempered with the needs of real-world applications by combining object-oriented techniques and procedural programming techniques to create a natural, easy-to-use and maintainable application.
You might be wondering what the differences are between these two programming techniques. We ll turn to English language syntax to describe the difference. Object-oriented programming groups things around nouns, such as customer and invoice , which you ll recognize as objects.
In contrast, procedural programming groups things around verbs. A verb in the real world is a task. This means the focus of a procedural programmer is on tasks that are performed by the application, whereas an object-oriented programmer focuses on an object, its data, and its behaviors.
Procedural programmers also use nouns (such as customer and invoice), too, but they are described in a database and not in the application code. For example, the task of searching for an invoice stored in a database is separate from the invoice itself. This means you don t need to create an object called invoice in order to search for an invoice. In object-oriented program, you need to create an invoice object because the search behavior is encapsulated in the invoice object.
Some programmers feel the basic premise that objects have behaviors isn t always true in the real world. It works well for GUI objects, but some real-world objects can be acted upon by behaviors of other objects or behaviors that are not associated with any object.
Take submitting an order form for processing as an example. Is this task associated with a sales representative object? How about a customer who directly places the order without the assistance of a sales representative? Maybe this is a stand-alone process that isn t associated directly with an object.
The real world doesn t necessarily restrict a task to an object, although object- oriented programming theory does require that a task be associated with an object. One of the challenges of applying object-oriented programming techniques is to know when to hold true to object-oriented programming theory and when to deviate from the theory to address real-world problems that cannot be handled efficiently using object-oriented programming techniques.
Object-oriented programming uses multilevel inheritance to avoid redundancy, but there is redundancy in the real world. For example, employees and customers both have contact information. An object-oriented programming approach might be to create an object called contact information that is inherited by objects called employee and customer . In the real world, contact information is directly related with an employee and customer without any inheritance.
Another underlying premise of object-oriented programming is that object-oriented programming is well-suited to simulate real-world objects in a computer application. This is true; however, many business applications do not simulate real-world business situations. A simulation is a technique that re-creates the real world in a computer in order to study how the real world works and how to improve a real-world process. In contrast, the purpose of a business application is to achieve a business objective using the best possible means. The reality is that simulating the real world does not necessarily use the best possible means to achieve a business objective.
Some programmers use airplanes and flying to illustrate the difference between simulating real life and achieving an objective using efficient means. Prior to the airplane, real-world flight was achieved by flapping wings. Therefore, if we set out to simulate flight, airplanes would have flapping wings ”and probably never would have gotten off the ground. Simulation, therefore, isn t a means to achieve the goal of flight.
On the surface, modeling the real world using object-oriented programming seems like a good way to develop a business application that simulates real-world business situations. However, simulation may not be the true objective of the application. Instead, the application s goal is to get something done efficiently. Blindly adhering to object-oriented programming design philosophies may not produce the best business application because object-oriented programming may not lend itself to designing an application that takes advantage of the strengths of computers.
Although we look at the real world in terms of objects, that view sometimes doesn t provide us with the flexibility needed to provide the best possible flow of a business application. Some programmers who strictly apply object-oriented programming design techniques to a business application may gloss over simplicity and efficiency in order to fit the theoretical design requirements. This results in failure to achieve the goal of the business application.
The objective of every programmer is to develop an application that improves the processing flow and not simply to mirror the real world. It doesn t make sense for an application to simulate every step in a manual process when the process can be reduced to fewer steps when performed by a computer.
You must strike a balance when using object-oriented programming to develop an application. The desire to simulate the real world by creating objects that have data and behaviors should not overshadow the need to develop an application that is efficient and improves the business process.
Programmers strike this balance by developing two models: the internal model and the external model. The internal model describes how an application works behind the scenes. The external model describes how a person interacts with the application.
In a perfect world, a programmer develops an application where both the internal and external models mirror real-world objects. For example, an order form is an object used to record and process a customer order. Ideally, the order form that appears on the screen should resemble the paper order form, thus enabling the user to relate the computerized order form to the real-world order form. Likewise, behind the scenes an order form object is created and is used to process order information.
In reality, the programmer probably uses the order form as the external model for an application, but might decide not to create an order form object for the internal model because it may not be the most efficient way to manage and process an order.
You should address the internal model and external model independently whenever you develop an application. Don t assume that you have to use object-oriented programming concepts to address every aspect of an application. Instead, apply those concepts that make sense for your application.
You won t be able to use hierarchical classification to describe every real-life object because the real world doesn t work that way. You might find yourself going to great lengths to develop a complex structure of objects in order to simulate the real world, when in reality you don t require such sophistication to achieve the business objective. Don t develop an object-oriented application in a vacuum . Always keep your sights on the objective of the application.
Sometimes you might discover that procedural and relational design techniques are much better suited for a portion of your application than object-oriented design. Procedural design focuses on tasks, which some programmers refer to as the verb approach because a procedure is an action. Relational design refers to application data stored in a relational database. Some programmers refer to this as the noun approach because, collectively, data describes a person, place, or thing.
One of the several attractions of a hierarchical solution is that we envision reuse of code in the base or super classes. Although this is always a key goal for professional developers, sometimes it just doesn t work. For example, we have discussed student classes extensively throughout this book. But, for all our design of these classes, they have no use if we are next asked to design an application to track stock quotes.
Although hierarchical design is always desirable, don t spend an inordinate amount of time trying to design systems solely for the purpose of the design. Use your common sense, run through several what if scenarios to see how things will work, and try to identify your reusable code and objects.
You will typically find that your code reuse and hierarchy fall into three categories: objects that are very reusable across different applications (such as a string class or stream hierarchy), objects that are reusable within a particular set of programs (such as our student class and hierarchy for academic institution programs), and objects that simply will never be reused again, anywhere .
A staple of object-oriented programming is to encapsulate tasks within a real-world object. However, sometimes this doesn t make sense because a task is associated with many objects instead of one object.
You ll run into this problem from time to time when developing an object-oriented program. Some programmers address this situation by creating a super class that defines the common task and then have objects that are associated with the task inherit the super class. Those subclasses can then call the task as required by the application.
Although this approach adheres to the principles of object-oriented programming, it can result in an overly complex application, especially if the only purpose of the super class is to facilitate the common task.
Professional programmers apply principles of object-oriented programming with a grain of common sense. Simplicity overrules the need to strictly adhere to object-oriented programming standards. They don t build classes simply to adhere to standards when a simpler alternative is available.
If there is a task that is associated with several classes, a programmer might consider defining a function that isn t a member of a class to handle the task. The function can be designed to use a variety of objects as required by the application. Those objects can be passed as parameters to the function.
Let s use the task of registering a student for a class as an example. Several approaches can be taken to implement the registration processing in an application. For example, you can define a separate class for each type of student ( undergraduate , graduate, postgraduate, continuing education) and then define a registration member function for each class.
The registration process is basically the same for all students; therefore, it might not make sense to have several definitions of the same function. Another alternative is to define a super class that contains the definition of the registration function. Each type of student class then can inherit the super class and gain access to the registration function.
The super class approach is ideal if there are other commonalities among each type of student class. Common data and functions can be defined in one place ”in the super class. This simplifies maintenance of the application.
Suppose the registration function is the only thing common among the types of student classes. Does it make sense to create a new super class for the sole purpose of defining the registration process? Some programmers will say yes, because doing so conforms to object-oriented programming conventions. Other programmers will disagree because doing so unnecessarily adds to the complexity of the application. A more desirable alternative is to define a registration function that isn t a member of a class. The registration function can be designed to register any type of student.
Sometimes the real world isn t built from well-defined objects, although object-oriented programming theory assumes this to be the case. This is apparent in business applications where data required by a process might come from multiple objects rather than encapsulated into one object.
A typical example of this is the month-end processing common to nearly all businesses. A month-end process summarizes the state of the business that occurs during the month. Data used for month-end processes typically comes from a variety of objects associated with multiple systems throughout the company.
For example, month-end processing summarizes customer account information, order information, and inventory information. Each of these is likely generated by an accounting system, transaction system, and inventory system. And within each of these systems is an assortment of objects, such as customer, product, and order.
It is difficult to associate the month-end process with a single object because no one object involved in the monthly summary process owns this process. A solution might be to define another object for the sole purpose of defining the month-end process. However, doing so unnecessarily complicates the application.
Therefore, modeling a real-world business using object-oriented programming isn t as straightforward as you might believe. There will be situations when the real world doesn t fit the theoretical object-oriented programming model, and you ll need to be less rigid in applying object-oriented programming theory to your application.
Developing a real-world object-oriented application is more challenging than the exercises used to explain the concepts of object-oriented programming. This is because only real-world objects that lend themselves to a class definition are used in those exercises.
Many instructors demonstrate the concept of object-oriented programming by using the example of an airplane or automobile, where the engine, wheels, and other components are objects contained by the airplane or automobile. These real-world objects fit nicely into an object definition. However, not all real-world objects do ”a factor that isn t mentioned in many books on object-oriented programming.
Some programmers question whether we really view the real world as objects and feel that we look at things as tasks and data rather than as objects. For example, when your house is hot, you probably think about lowering the temperature by turning on the air conditioner or by opening a window. You don t think air condition, turn on, or window, open , which is the logic used if you thought about objects first and then the behaviors associated with those objects.
This subtle difference can become a mental roadblock for programmers who model the real world in a computer application because programmers tend to mimic the way we look at the real world. Programmers have to alter their natural thinking process in order to model the real world.
Data is another mental stumbling block when modeling the real world using object-oriented programming. Data is encapsulated in an object according to object-oriented programming theory. There are few data elements in an application that aren t encapsulated with an object.
The difficulty occurs when storing data in a database. Although there are object-oriented databases, many programmers use one of the popular relational databases, such as Oracle, DB2, or Sybase, as data storage for their applications.
A relational database doesn t store objects; it stores data . This means the programmer must write routines that extract encapsulated data in a form where data can be stored in a relational database. Likewise, data retrieved from a relational database must be restructured so that data can be encapsulated into one or more objects in the application.
Sometimes programmers build conversion routines into the member functions of an object that are used to extract and restructure data to and from a relational database. Other times programmers develop middleware software that sits between the application and the relational database. Middleware software contains conversion routines that interact with both the object-oriented application and the relational database.
A conversion routine maps fields to the data members of objects, and it maps data members of objects to the fields of a relational database. This is a time-consuming process that is required only because data is encapsulated in an object. Some programmers feel conversion routines unnecessarily complicate an application ”these routines are required only because the application is written using an object-oriented programming language and not because they are a requirement of the application.