Now that you understand many of the challenges you ll face applying object-oriented programming theory in real-world situations, let s take a closer look at common problems and how the pros resolve them. Here s what we ll explore:
Data storage is a common challenge when designing an object-oriented program because there is a philosophical conflict between the way many organizations store data and object-oriented programming design, as you learned in this chapter.
Organizations use a relational database to store data, which coincides with the procedural style of programming. Objects defined in object-oriented programming don t lend themselves easily to a relational database model because a relational database is not suited for storing objects. An object-oriented database is designed to store objects; however, typically organizations don t use an object-oriented database.
Your problem is how to resolve this conflict when writing an object-oriented program that requires data storage. Professional programmers address this issue by writing functions that translate data members of objects to a relational database model, and vice versa.
To do this requires four functions: insert() , search() , modify() , and delete() . The insert() function converts data members of objects defined by your application into data elements, and it organizes the data elements into one or more records required by the corresponding relational database. The insert() function also contains the SQL query that places these records into the database.
The search() function retrieves one or more records from the relational database. It does this by using a query to find the search criteria for the record and then converting the returning record into the data members of a corresponding object within the application. The object is then typically displayed on the screen.
The search() function is used in conjunction with the modify() and delete() functions. After the desired data is displayed, the user of the application causes the modify() or delete() function to be executed. The modify() function enables the user to change the data of an object that was retrieved from the database. It then converts the data members of the object to its corresponding record and then updates the record in the relational database. The delete() function removes the record from the database.
Previously in this chapter, you learned how object-oriented programming and the real world don t always compliment each other. The real world cannot always be nicely organized into discrete objects. You should expect to run into conflicts between how the real world works and object-oriented programming philosophy.
A common conflict occurs with procedures. Procedures should be encapsulated within an object definition. Yet there are times when a procedure crosses the boundary of two or more objects. It doesn t make sense to encapsulate into any one object. This situation leaves programmers in a dilemma of where to define the procedure in the application.
According to the spirit of object-oriented programming, the programmers should define an object that encapsulates the procedure and then have other objects inherit it. In this way, the procedure is available to multiple objects without having to repeat the procedure.
Although this approach is totally acceptable, it can lead to overly complex code that contains too many objects for an application programmer to learn and remember. This is especially true if there are many situations within the application where procedures can be associated with more than one object.
Here s what to do when you encounter this conflict. Balance the need to adhere to object-oriented design philosophy and the need for an uncomplicated application. If the sole purpose of defining an object is to accommodate a procedure, then consider defining the procedure as a stand-alone procedure rather than defining another object. A stand-alone procedure is acceptable in an object-oriented program if it makes sense to the application.
On the other hand, if the procedure can be encapsulated in an object that contains other procedures that are common across my objects, then define a new object. It makes sense to do so because the object can be used to accommodate more than one procedure.
Identifying objects in the real world seems intuitive, but it can become challenging when you actually have to define objects for your application because some real-world things could be interpreted as two or more objects.
Take a student as an example. A student is an obvious object. However, there is more than one kind of student. There are undergraduate students, graduate students, postgraduate students, and continuing education students. Each kind of student can be its own object. Alternatively, student can be the object, and attributes of student could describe the kind of student.
You ll run into similar conflicts when developing an object-oriented application. Programmers resolve such conflicts by developing a keep it simple philosophy. Avoid creating too many objects in an application. Don t divide an object into many objects unless there is a compelling reason to do so. Instead, define one object and use attributes and member procedures to make the distinction among the different kinds of objects.
Throughout the examples in this book we ve defined objects for each kind of student because we used these objects to illustrate various features of object-oriented programming. However, baring any unique requirement of an application, it makes sense to define one object called student and then define attributes and member procedures to distinguish each kind of student.
In general, the fewer objects that are defined in application, the easier it will be for programmers to understand and maintain the code of an application. Some programmers only define objects that directly correspond to major entities of a real-world process, such as a customer, product, order form, invoice, and sales representative. They avoid defining objects for the sake of adhering to strict object-oriented design philosophy because doing so has a tendency to make an application overly and unnecessarily complex.
There is a tendency for programmers who recently discover the power of object-oriented programming to go wild creating a complex hierarchy for their applications and lose track of the application s goal. In doing so they create multilevel inheritance that is technically sound, but a challenge to maintain.
Avoid creating unnecessary inheritance, especially inheritance that involves more than three levels. Most real-world applications will be operational for years and maintained and enhanced by a series of programmers who need to focus on upgrading the code rather than learning a complex trail of inheritance within the application.
As a general rule, keep the hierarchy of your application to no more than three levels of inheritance, unless additional levels have a direct, positive impact on achieving the objective of the application. If the additional levels won t materially improve the application, then don t implement those levels in your program.