Object-Oriented Development:
This paper is an overview of the issues that arise from implementing object persistence with a relational database. The basis for this paper is our recent experience with Object-Oriented projects that used relational database technology. Those experiences have shown us that the cost of mixing the two paradigms is very high and can seriously detract from the benefits of Object-Oriented development. There is no question that object-to-relational solutions can be made to work, but at what price? This paper describes approaches to building object-to-relational bridges and highlights problems and compromises that typically arise. This is not a guide to implementing an object-to-relational bridge; instead, its purpose is to explain some fundamental issues and provide information that would be useful in making a database technology selection. This paper is most pertinent in the context of programming languages that have little or no native support for object persistence, such as C++.
Our intent with this paper is to show how object-to-relational solutions often deny projects many of the benefits of Object-Oriented development, such as flexibility, reuse, and simplicity. This denial is a natural consequence of object persistence in languages such as C++ and is difficult to overcome. Even with the proliferation of in-house object-to-relational solutions, it has seldom been our experience that object-to-relational translation is robust enough to adequately preserve the spirit of Object-Oriented development.
This is not to say that these solutions do not work, that is if "work" is defined as "able to move data between an Object-Oriented application and a relational database". However, if "work" is defined more strongly to include assurances regarding the integrity of object associations, high performance, and preservation of the principle of implementation hiding these solutions typically fail. It should be noted that implementation hiding is a central goal in Object-Oriented software development, a principle that is difficult to preserve in an application that uses object-to-relational translation.
The two most common pitfalls of object-to-relational translation are 1) the bloat of programming not germane to the software's purpose, and 2) the introduction of explicit and implicit software dependencies due to translating complex relationships. Solutions that are naive to the special challenges of object persistence will aggravate this further, but the problems are mostly intrinsic and are difficult to avoid even under the most accommodating circumstances. In building object-to-relational translation software we are challenged to implement object persistence without violating the independence or cohesiveness of objects.
The difficulties associated with doing this are exacerbated by a relational database's need to use foreign keys as a means of implementing relationships. Commercial tools offer a modicum of relief but many projects choose to build their own object-to-relational solution rather than buy one. Moreover, many architects will still choose building over buying, often due to having underestimated the complexity of this problem. Such projects tend to suffer with primitive and insufficient language bindings, a major source of unwanted software rigidity caused by object-to-relational solutions.
This paper concerns the use of a relational database to save and reconstitute objects from an Object-Oriented application. There are two ways to view this. The first is true persistent objects, where whole objects and their relationships must be persistent. Think of these objects as "sleeping" when they are in a database. The other is to assume that data are of primary importance, and objects are merely a necessary side effect of computation. This will be the case if a database schema is a controlled interface or is shared by several different software clients.
Typically in these situations the data schema is a separately controlled design and the values in database tables have uses beyond the context of sleeping objects. In either of these cases a major challenge is to implement Object-Oriented software without allowing an object-to-relational solution to force undesirable coupling between software components at the application level of architecture. The issue cannot be sidestepped by assuming a database need only see objects as mere data; data that can be loaded into C-style structures and persisted by some kind of "access module" or "access class". Trying to think of objects as merely data is not a solution, mostly because there are no good methods of extracting the data in a way that is transparent to the objects.