Rogue Wave banner
Previous fileTop of DocumentContentsIndexNext file

2.3 Producers and Products

Access libraries contain the derived, database-dependent variants of the implementation classes. You don't even have to think about these classes; you deal only with the portable semantics defined by the DBTools.h++ core library. It is the responsibility of the core library to provide your application with the correct variant. The core library does this by using what is called the Producer/Product paradigm, which is sometimes referred to as the factory or kit approach.

Under the Producer/Product paradigm, an application obtains object instances (Products) by requesting them from other object instances (Producers), rather than by invoking a constructor. Using this paradigm, DBTools.h++ ensures that all objects with database-dependent variants are correctly typed. An Oracle RWDBDatabase can only produce Oracle RWDBTables; a Sybase RWDBTable can only produce Sybase RWDBReaders, and so on.


NOTE: The main point to remember is to get database-dependent objects from object producers, not from constructors.

By convention, the name of the method that a producer uses to produce a product is the name of the product minus the RWDB prefix. In the following example, an RWDBReader is obtained from an RWDBTable, which was obtained from an RWDBDatabase, which was obtained from the RWDBManager:

Class RWDBManager is at the root of the tree of object producers. An application specifies a database type to the RWDBManager by including the name of an access library, as well as other information necessary for establishing a database session. The RWDBManager negotiates with the named access library in order to produce a correctly typed RWDBDatabase instance. Notice the call to RWDBManager::database(). From this point on, database details are no longer visible. The RWDBTable and RWDBReader instances in the example above are guaranteed to have the same database-dependent implementations as the objects that produced them. The arguments required to open a database connection are specified in the Databases and Connections sections in the access library guides.

Why use producers instead of constructors? Some developers may suggest that the database-dependent typing of classes could be solved by using the producer as an argument to an object constructor. DBTools.h++ uses producers rather than constructors to avoid the C++ pitfall associated with constructors that take a single argument: it is easy to forget that such a constructor implies an automatic type conversion. For example, the last line of the previous example could have been:

If this syntax were allowed, any function requiring an RWDBReader would also accept an RWDBTable, that is, automatic type conversion of RWDBTable to RWDBReader. This is a potential source of error that we want to avoid.

Figure 4 shows the Producer/Product relationship among the DBTools.h++ database-dependent classes. At the root of the tree, class RWDBManager is responsible for producing database-dependent RWDBDatabase instances. Classes produced by RWDBDatabase are indented one level below RWDBDatabase, and so on.

Some class names appear more than once in Table 4. This is because certain classes have more than one producer. For example, to read an RWDBTable, you request an RWDBReader from the RWDBTable you want to read; to read the results of a SELECT statement, you request an RWDBReader from an RWDBSelector.

Figure 4 -- The DBTools.h++ Producer/Product hierarchy for database-dependent classes. Indentation levels indicate the relationship between producer and product. An indented class is produced by the previous less-indented class. Note that some classes are produced by more than one other class, and therefore appear more than once.

Producer/Product Hierarchy
Previous fileTop of DocumentContentsIndexNext file

©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.