The design of DBTools.h++ uses the Interface/Implementation paradigm. Interface classes model objects in the application domain. Each interface class has an associated implementation class, which is used to implement the semantics defined by the interface class.
NOTE: Interface classes are public, and model objects in the application domain. Implementation classes are private, and implement the semantics of their associated interface classes.
This paradigm is familiar to most C++ programmers. For example, many beginning texts present examples of simple classes like string that follow the paradigm. A typical string class might be designed as an interface class that defines the semantics of the class and contains a pointer to a reference-counted implementation class, which provides the services of data storage, memory management, and so on.
The public class hierarchy of DBTools.h++ consists of a set of interface classes that are concrete, as opposed to abstract. These concrete classes function as is without requiring further derivation. As interface classes, they do no work and store no data themselves. Instead, each interface class instance consists of a pointer to an implementation class instance, and forwards all function calls to it. The implementation classes are not part of the public hierarchy. Only the interface classes are visible to the application programmer.
The interface classes are divided into classes that contain a pointer to a database-dependent implementation and those that do not. In general, classes that model database concepts, like RWDBTable and RWDBSelector, have pointers to database-dependent implementations, while classes that model database-independent concepts, like RWDBDateTime and RWDBExpr, do not. Figure 2 shows the class hierarchy of the public DBTools.h++ classes.
Note that all DBTools.h++ implementation classes can be considered abstract classes, containing virtual functions. These virtual functions will be overridden in the derived classes that make up the database-dependent access libraries.
For example, class RWDBDatabase is an abstraction that represents a database. It offers a rich set of semantics: you have access to database objects like tables, views, and stored procedures; you can manage multiple connections; and you can use database definition language (DDL) constructs, among other things.
These semantic elements represent features common to all databases. However, the way a feature is implemented for any particular database depends heavily upon the API provided by the database manufacturer. Consequently, RWDBDatabaseImp, the implementation class associated with RWDBDatabase, is an abstract base class for a family of database-dependent implementation classes-one implementation class for each database manufacturer that DBTools.h++ supports. These database-dependent implementation classes make up the access library for the particular database. Figure 3 shows this relationship.
Notice also from Figure3 that classes RWDBDatabase and RWDBDatabaseImp reside in the DBTools.h++ core library, while RWDBSybDbLibDatabaseImp and RWDBOracleDatabaseImp reside in separate DBTools.h++ access libraries. This is the key to database portability in DBTools.h++. The core library--and therefore, your application--doesn't care which databases it works with. The core library serves as a software backplane for plugging in different access libraries interchangeably. When using shared libraries or DLLs, you can even plug in access libraries at runtime without relinking your application.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.